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