1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Database\Conventions;
9:
10: use Nette\Database\IConventions;
11: use Nette\Database\IStructure;
12:
13:
14: 15: 16:
17: class DiscoveredConventions implements IConventions
18: {
19:
20: protected $structure;
21:
22:
23: public function __construct(IStructure $structure)
24: {
25: $this->structure = $structure;
26: }
27:
28:
29: public function getPrimary($table)
30: {
31: return $this->structure->getPrimaryKey($table);
32: }
33:
34:
35: public function getHasManyReference($nsTable, $key)
36: {
37: $candidates = $columnCandidates = [];
38: $targets = $this->structure->getHasManyReference($nsTable);
39: $table = preg_replace('#^(.*\.)?(.*)$#', '$2', $nsTable);
40:
41: foreach ($targets as $targetNsTable => $targetColumns) {
42: $targetTable = preg_replace('#^(.*\.)?(.*)$#', '$2', $targetNsTable);
43: if (stripos($targetNsTable, $key) === false) {
44: continue;
45: }
46:
47: foreach ($targetColumns as $targetColumn) {
48: if (stripos($targetColumn, $table) !== false) {
49: $columnCandidates[] = $candidate = [$targetNsTable, $targetColumn];
50: if (strcmp($targetTable, $key) === 0 || strcmp($targetNsTable, $key) === 0) {
51: return $candidate;
52: }
53: }
54:
55: $candidates[] = [$targetTable, [$targetNsTable, $targetColumn]];
56: }
57: }
58:
59: if (count($columnCandidates) === 1) {
60: return $columnCandidates[0];
61: } elseif (count($candidates) === 1) {
62: return $candidates[0][1];
63: }
64:
65: foreach ($candidates as $candidate) {
66: if (strtolower($candidate[0]) === strtolower($key)) {
67: return $candidate[1];
68: }
69: }
70:
71: if (!empty($candidates)) {
72: throw new AmbiguousReferenceKeyException('Ambiguous joining column in related call.');
73: }
74:
75: if ($this->structure->isRebuilt()) {
76: return null;
77: }
78:
79: $this->structure->rebuild();
80: return $this->getHasManyReference($nsTable, $key);
81: }
82:
83:
84: public function getBelongsToReference($table, $key)
85: {
86: $tableColumns = $this->structure->getBelongsToReference($table);
87:
88: foreach ($tableColumns as $column => $targetTable) {
89: if (stripos($column, $key) !== false) {
90: return [$targetTable, $column];
91: }
92: }
93:
94: if ($this->structure->isRebuilt()) {
95: return null;
96: }
97:
98: $this->structure->rebuild();
99: return $this->getBelongsToReference($table, $key);
100: }
101: }
102: