Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
Traverser
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 4
182
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 ancestors
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 descendants
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 visit
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace MediaWiki\Extension\Genealogy;
4
5class Traverser {
6
7    /** @var callable[] */
8    private $callbacks;
9
10    /** @var int */
11    private $ancestorDepth = 0;
12
13    /** @var int */
14    private $descendantDepth = 0;
15
16    /**
17     * Callbacks will be called for each page crawled.
18     *
19     * @param callable $callback The callable function etc.
20     */
21    public function register( $callback ) {
22        $this->callbacks[] = $callback;
23    }
24
25    /**
26     * Traverse all ancestors.
27     * @param Person $person The person to start at.
28     * @param int|null $depth The height to ascend to.
29     */
30    public function ancestors( Person $person, $depth = null ) {
31        // Visit this person and their partners.
32        $this->visit( $person );
33        foreach ( $person->getPartners() as $partner ) {
34            $this->visit( $partner );
35        }
36        // Give up if we're being limited.
37        if ( $depth !== null ) {
38            $this->ancestorDepth++;
39            if ( $this->ancestorDepth >= $depth ) {
40                return;
41            }
42        }
43        // Carry on to their ancestors.
44        foreach ( $person->getParents() as $parent ) {
45            $this->ancestors( $parent, $depth );
46        }
47    }
48
49    /**
50     * Traverse all descendants.
51     * @param Person $person The person to start at.
52     * @param int|null $depth The depth to descend to.
53     */
54    public function descendants( Person $person, $depth = null ) {
55        // Visit this person and their partners.
56        $this->visit( $person );
57        foreach ( $person->getPartners() as $partner ) {
58            $this->visit( $partner );
59        }
60        // Give up if we're being limited.
61        if ( $depth !== null ) {
62            $this->descendantDepth++;
63            if ( $this->descendantDepth >= $depth ) {
64                return;
65            }
66        }
67        // Carry on to their descendants.
68        foreach ( $person->getChildren() as $child ) {
69            $this->descendants( $child, $depth );
70        }
71    }
72
73    /**
74     * When traversing a tree, each node is 'visited' and its callbacks called.
75     * @param Person $person
76     */
77    protected function visit( $person ) {
78        // Call each callback
79        foreach ( $this->callbacks as $callback ) {
80            call_user_func( $callback, $person );
81        }
82    }
83
84}