Passed
Push — 1.7 ( 4c1abf...23cbb7 )
by Greg
08:10
created
app/Controller/RelationshipController.php 1 patch
Indentation   +185 added lines, -185 removed lines patch added patch discarded remove patch
@@ -25,190 +25,190 @@
 block discarded – undo
25 25
  * Controller for the relationships calculations
26 26
  */
27 27
 class RelationshipController extends PageController {
28
-	/**
29
-	 * Calculate the shortest paths - or all paths - between two individuals.
30
-	 *
31
-	 * @param Individual $individual1
32
-	 * @param Individual $individual2
33
-	 * @param int        $recursion   How many levels of recursion to use
34
-	 * @param boo;       $ancestor    Restrict to relationships via a common ancestor
35
-	 *
36
-	 * @return string[][]
37
-	 */
38
-	public function calculateRelationships(Individual $individual1, Individual $individual2, $recursion, $ancestor = false) {
39
-
40
-		$rows = Database::prepare(
41
-			"SELECT l_from, l_to FROM `##link` WHERE l_file = :tree_id AND l_type IN ('FAMS', 'FAMC')"
42
-		)->execute(array(
43
-			'tree_id' => $individual1->getTree()->getTreeId(),
44
-		))->fetchAll();
45
-
46
-		// Optionally restrict the graph to the ancestors of the individuals.
47
-		if ($ancestor) {
48
-			$ancestors = $this->allAncestors($individual1->getXref(), $individual2->getXref(), $individual1->getTree()->getTreeId());
49
-			$exclude   = $this->excludeFamilies($individual1->getXref(), $individual2->getXref(), $individual1->getTree()->getTreeId());
50
-		} else {
51
-			$ancestors = array();
52
-			$exclude   = array();
53
-		}
54
-
55
-		$graph = array();
56
-
57
-		foreach ($rows as $row) {
58
-			if (!$ancestors || in_array($row->l_from, $ancestors) && !in_array($row->l_to, $exclude)) {
59
-				$graph[$row->l_from][$row->l_to] = 1;
60
-				$graph[$row->l_to][$row->l_from] = 1;
61
-			}
62
-		}
63
-
64
-		$xref1    = $individual1->getXref();
65
-		$xref2    = $individual2->getXref();
66
-		$dijkstra = new Dijkstra($graph);
67
-		$paths    = $dijkstra->shortestPaths($xref1, $xref2);
68
-
69
-		// Only process each exclusion list once;
70
-		$excluded = array();
71
-
72
-		$queue = array();
73
-		foreach ($paths as $path) {
74
-			// Insert the paths into the queue, with an exclusion list.
75
-			$queue[] = array('path' => $path, 'exclude' => array());
76
-			// While there are un-extended paths
28
+    /**
29
+     * Calculate the shortest paths - or all paths - between two individuals.
30
+     *
31
+     * @param Individual $individual1
32
+     * @param Individual $individual2
33
+     * @param int        $recursion   How many levels of recursion to use
34
+     * @param boo;       $ancestor    Restrict to relationships via a common ancestor
35
+     *
36
+     * @return string[][]
37
+     */
38
+    public function calculateRelationships(Individual $individual1, Individual $individual2, $recursion, $ancestor = false) {
39
+
40
+        $rows = Database::prepare(
41
+            "SELECT l_from, l_to FROM `##link` WHERE l_file = :tree_id AND l_type IN ('FAMS', 'FAMC')"
42
+        )->execute(array(
43
+            'tree_id' => $individual1->getTree()->getTreeId(),
44
+        ))->fetchAll();
45
+
46
+        // Optionally restrict the graph to the ancestors of the individuals.
47
+        if ($ancestor) {
48
+            $ancestors = $this->allAncestors($individual1->getXref(), $individual2->getXref(), $individual1->getTree()->getTreeId());
49
+            $exclude   = $this->excludeFamilies($individual1->getXref(), $individual2->getXref(), $individual1->getTree()->getTreeId());
50
+        } else {
51
+            $ancestors = array();
52
+            $exclude   = array();
53
+        }
54
+
55
+        $graph = array();
56
+
57
+        foreach ($rows as $row) {
58
+            if (!$ancestors || in_array($row->l_from, $ancestors) && !in_array($row->l_to, $exclude)) {
59
+                $graph[$row->l_from][$row->l_to] = 1;
60
+                $graph[$row->l_to][$row->l_from] = 1;
61
+            }
62
+        }
63
+
64
+        $xref1    = $individual1->getXref();
65
+        $xref2    = $individual2->getXref();
66
+        $dijkstra = new Dijkstra($graph);
67
+        $paths    = $dijkstra->shortestPaths($xref1, $xref2);
68
+
69
+        // Only process each exclusion list once;
70
+        $excluded = array();
71
+
72
+        $queue = array();
73
+        foreach ($paths as $path) {
74
+            // Insert the paths into the queue, with an exclusion list.
75
+            $queue[] = array('path' => $path, 'exclude' => array());
76
+            // While there are un-extended paths
77 77
             for ($next = current($queue); $next !== false; $next = next($queue)) {
78
-				// For each family on the path
79
-				for ($n = count($next['path']) - 2; $n >= 1; $n -= 2) {
80
-					$exclude = $next['exclude'];
81
-					if (count($exclude) >= $recursion) {
82
-						continue;
83
-					}
84
-					$exclude[] = $next['path'][$n];
85
-					sort($exclude);
86
-					$tmp = implode('-', $exclude);
87
-					if (in_array($tmp, $excluded)) {
88
-						continue;
89
-					} else {
90
-						$excluded[] = $tmp;
91
-					}
92
-					// Add any new path to the queue
93
-					foreach ($dijkstra->shortestPaths($xref1, $xref2, $exclude) as $new_path) {
94
-						$queue[] = array('path' => $new_path, 'exclude' => $exclude);
95
-					}
96
-				}
97
-			}
98
-		}
99
-		// Extract the paths from the queue, removing duplicates.
100
-		$paths = array();
101
-		foreach ($queue as $next) {
102
-			$paths[implode('-', $next['path'])] = $next['path'];
103
-		}
104
-
105
-		return $paths;
106
-	}
107
-
108
-	/**
109
-	 * Convert a path (list of XREFs) to an "old-style" string of relationships.
110
-	 *
111
-	 * Return an empty array, if privacy rules prevent us viewing any node.
112
-	 *
113
-	 * @param GedcomRecord[] $path Alternately Individual / Family
114
-	 *
115
-	 * @return string[]
116
-	 */
117
-	public function oldStyleRelationshipPath(array $path) {
118
-		global $WT_TREE;
119
-
120
-		$spouse_codes  = array('M' => 'hus', 'F' => 'wif', 'U' => 'spo');
121
-		$parent_codes  = array('M' => 'fat', 'F' => 'mot', 'U' => 'par');
122
-		$child_codes   = array('M' => 'son', 'F' => 'dau', 'U' => 'chi');
123
-		$sibling_codes = array('M' => 'bro', 'F' => 'sis', 'U' => 'sib');
124
-		$relationships = array();
125
-
126
-		for ($i = 1; $i < count($path); $i += 2) {
127
-			$family = Family::getInstance($path[$i], $WT_TREE);
128
-			$prev   = Individual::getInstance($path[$i - 1], $WT_TREE);
129
-			$next   = Individual::getInstance($path[$i + 1], $WT_TREE);
130
-			if (preg_match('/\n\d (HUSB|WIFE|CHIL) @' . $prev->getXref() . '@/', $family->getGedcom(), $match)) {
131
-				$rel1 = $match[1];
132
-			} else {
133
-				return array();
134
-			}
135
-			if (preg_match('/\n\d (HUSB|WIFE|CHIL) @' . $next->getXref() . '@/', $family->getGedcom(), $match)) {
136
-				$rel2 = $match[1];
137
-			} else {
138
-				return array();
139
-			}
140
-			if (($rel1 === 'HUSB' || $rel1 === 'WIFE') && ($rel2 === 'HUSB' || $rel2 === 'WIFE')) {
141
-				$relationships[$i] = $spouse_codes[$next->getSex()];
142
-			} elseif (($rel1 === 'HUSB' || $rel1 === 'WIFE') && $rel2 === 'CHIL') {
143
-				$relationships[$i] = $child_codes[$next->getSex()];
144
-			} elseif ($rel1 === 'CHIL' && ($rel2 === 'HUSB' || $rel2 === 'WIFE')) {
145
-				$relationships[$i] = $parent_codes[$next->getSex()];
146
-			} elseif ($rel1 === 'CHIL' && $rel2 === 'CHIL') {
147
-				$relationships[$i] = $sibling_codes[$next->getSex()];
148
-			}
149
-		}
150
-
151
-		return $relationships;
152
-	}
153
-
154
-	/**
155
-	 * Find all ancestors of a list of individuals
156
-	 *
157
-	 * @param string $xref1
158
-	 * @param string $xref2
159
-	 * @param int    $tree_id
160
-	 *
161
-	 * @return array
162
-	 */
163
-	private function allAncestors($xref1, $xref2, $tree_id) {
164
-		$ancestors = array($xref1, $xref2);
165
-
166
-		$queue = array($xref1, $xref2);
167
-		while (!empty($queue)) {
168
-			$placeholders = implode(',', array_fill(0, count($queue), '?'));
169
-			$parameters = $queue;
170
-			$parameters[] = $tree_id;
171
-
172
-			$parents = Database::prepare(
173
-				"SELECT l2.l_from" .
174
-				" FROM `##link` AS l1" .
175
-				" JOIN `##link` AS l2 USING (l_to, l_file) " .
176
-				" WHERE l1.l_type = 'FAMC' AND l2.l_type = 'FAMS' AND l1.l_from IN (" . $placeholders . ") AND l_file = ?"
177
-			)->execute(
178
-				$parameters
179
-			)->fetchOneColumn();
180
-
181
-			$queue = array();
182
-			foreach ($parents as $parent) {
183
-				if (!in_array($parent, $ancestors)) {
184
-					$ancestors[] = $parent;
185
-					$queue[]     = $parent;
186
-				}
187
-			}
188
-		}
189
-
190
-		return $ancestors;
191
-	}
192
-
193
-	/**
194
-	 * Find all families of two individuals
195
-	 *
196
-	 * @param string $xref1
197
-	 * @param string $xref2
198
-	 * @param int    $tree_id
199
-	 *
200
-	 * @return array
201
-	 */
202
-	private function excludeFamilies($xref1, $xref2, $tree_id) {
203
-		return Database::prepare(
204
-			"SELECT l_to" .
205
-			" FROM `##link` AS l1" .
206
-			" JOIN `##link` AS l2 USING (l_type, l_to, l_file) " .
207
-			" WHERE l_type = 'FAMS' AND l1.l_from = :spouse1 AND l2.l_from = :spouse2 AND l_file = :tree_id"
208
-		)->execute(array(
209
-			'spouse1' => $xref1,
210
-			'spouse2' => $xref2,
211
-			'tree_id' => $tree_id,
212
-		))->fetchOneColumn();
213
-	}
78
+                // For each family on the path
79
+                for ($n = count($next['path']) - 2; $n >= 1; $n -= 2) {
80
+                    $exclude = $next['exclude'];
81
+                    if (count($exclude) >= $recursion) {
82
+                        continue;
83
+                    }
84
+                    $exclude[] = $next['path'][$n];
85
+                    sort($exclude);
86
+                    $tmp = implode('-', $exclude);
87
+                    if (in_array($tmp, $excluded)) {
88
+                        continue;
89
+                    } else {
90
+                        $excluded[] = $tmp;
91
+                    }
92
+                    // Add any new path to the queue
93
+                    foreach ($dijkstra->shortestPaths($xref1, $xref2, $exclude) as $new_path) {
94
+                        $queue[] = array('path' => $new_path, 'exclude' => $exclude);
95
+                    }
96
+                }
97
+            }
98
+        }
99
+        // Extract the paths from the queue, removing duplicates.
100
+        $paths = array();
101
+        foreach ($queue as $next) {
102
+            $paths[implode('-', $next['path'])] = $next['path'];
103
+        }
104
+
105
+        return $paths;
106
+    }
107
+
108
+    /**
109
+     * Convert a path (list of XREFs) to an "old-style" string of relationships.
110
+     *
111
+     * Return an empty array, if privacy rules prevent us viewing any node.
112
+     *
113
+     * @param GedcomRecord[] $path Alternately Individual / Family
114
+     *
115
+     * @return string[]
116
+     */
117
+    public function oldStyleRelationshipPath(array $path) {
118
+        global $WT_TREE;
119
+
120
+        $spouse_codes  = array('M' => 'hus', 'F' => 'wif', 'U' => 'spo');
121
+        $parent_codes  = array('M' => 'fat', 'F' => 'mot', 'U' => 'par');
122
+        $child_codes   = array('M' => 'son', 'F' => 'dau', 'U' => 'chi');
123
+        $sibling_codes = array('M' => 'bro', 'F' => 'sis', 'U' => 'sib');
124
+        $relationships = array();
125
+
126
+        for ($i = 1; $i < count($path); $i += 2) {
127
+            $family = Family::getInstance($path[$i], $WT_TREE);
128
+            $prev   = Individual::getInstance($path[$i - 1], $WT_TREE);
129
+            $next   = Individual::getInstance($path[$i + 1], $WT_TREE);
130
+            if (preg_match('/\n\d (HUSB|WIFE|CHIL) @' . $prev->getXref() . '@/', $family->getGedcom(), $match)) {
131
+                $rel1 = $match[1];
132
+            } else {
133
+                return array();
134
+            }
135
+            if (preg_match('/\n\d (HUSB|WIFE|CHIL) @' . $next->getXref() . '@/', $family->getGedcom(), $match)) {
136
+                $rel2 = $match[1];
137
+            } else {
138
+                return array();
139
+            }
140
+            if (($rel1 === 'HUSB' || $rel1 === 'WIFE') && ($rel2 === 'HUSB' || $rel2 === 'WIFE')) {
141
+                $relationships[$i] = $spouse_codes[$next->getSex()];
142
+            } elseif (($rel1 === 'HUSB' || $rel1 === 'WIFE') && $rel2 === 'CHIL') {
143
+                $relationships[$i] = $child_codes[$next->getSex()];
144
+            } elseif ($rel1 === 'CHIL' && ($rel2 === 'HUSB' || $rel2 === 'WIFE')) {
145
+                $relationships[$i] = $parent_codes[$next->getSex()];
146
+            } elseif ($rel1 === 'CHIL' && $rel2 === 'CHIL') {
147
+                $relationships[$i] = $sibling_codes[$next->getSex()];
148
+            }
149
+        }
150
+
151
+        return $relationships;
152
+    }
153
+
154
+    /**
155
+     * Find all ancestors of a list of individuals
156
+     *
157
+     * @param string $xref1
158
+     * @param string $xref2
159
+     * @param int    $tree_id
160
+     *
161
+     * @return array
162
+     */
163
+    private function allAncestors($xref1, $xref2, $tree_id) {
164
+        $ancestors = array($xref1, $xref2);
165
+
166
+        $queue = array($xref1, $xref2);
167
+        while (!empty($queue)) {
168
+            $placeholders = implode(',', array_fill(0, count($queue), '?'));
169
+            $parameters = $queue;
170
+            $parameters[] = $tree_id;
171
+
172
+            $parents = Database::prepare(
173
+                "SELECT l2.l_from" .
174
+                " FROM `##link` AS l1" .
175
+                " JOIN `##link` AS l2 USING (l_to, l_file) " .
176
+                " WHERE l1.l_type = 'FAMC' AND l2.l_type = 'FAMS' AND l1.l_from IN (" . $placeholders . ") AND l_file = ?"
177
+            )->execute(
178
+                $parameters
179
+            )->fetchOneColumn();
180
+
181
+            $queue = array();
182
+            foreach ($parents as $parent) {
183
+                if (!in_array($parent, $ancestors)) {
184
+                    $ancestors[] = $parent;
185
+                    $queue[]     = $parent;
186
+                }
187
+            }
188
+        }
189
+
190
+        return $ancestors;
191
+    }
192
+
193
+    /**
194
+     * Find all families of two individuals
195
+     *
196
+     * @param string $xref1
197
+     * @param string $xref2
198
+     * @param int    $tree_id
199
+     *
200
+     * @return array
201
+     */
202
+    private function excludeFamilies($xref1, $xref2, $tree_id) {
203
+        return Database::prepare(
204
+            "SELECT l_to" .
205
+            " FROM `##link` AS l1" .
206
+            " JOIN `##link` AS l2 USING (l_type, l_to, l_file) " .
207
+            " WHERE l_type = 'FAMS' AND l1.l_from = :spouse1 AND l2.l_from = :spouse2 AND l_file = :tree_id"
208
+        )->execute(array(
209
+            'spouse1' => $xref1,
210
+            'spouse2' => $xref2,
211
+            'tree_id' => $tree_id,
212
+        ))->fetchOneColumn();
213
+    }
214 214
 }
Please login to merge, or discard this patch.