Wilkins has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/245905

Change subject: Refactoring the FamilyTree calls with a FamilyTreeFactory into 
the SpecialPage and the FamilyTreeTag object
......................................................................

Refactoring the FamilyTree calls with a FamilyTreeFactory into the SpecialPage 
and the FamilyTreeTag object

Change-Id: I02693b0020e2e111e3f39b94ee4f5e8530f8127e
---
A AncestorsFamilyTree.php
A DescendantFamilyTree.php
M FamilyTree.php
A FamilyTreeFactory.php
M FamilyTreeTag.php
M PersonPageValues.php
A RelationFamilyTree.php
M SemanticGenealogy.php
M SpecialFamilyTree.php
9 files changed, 597 insertions(+), 362 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticGenealogy 
refs/changes/05/245905/1

diff --git a/AncestorsFamilyTree.php b/AncestorsFamilyTree.php
new file mode 100644
index 0000000..a527e20
--- /dev/null
+++ b/AncestorsFamilyTree.php
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * AncestorsFamilyTree object
+ *
+ * Handle a FamilyTree to display the ancestors of the person
+ * 
+ * @file AncestorsFamilyTree.php
+ * @ingroup SemanticGenealogy
+ *
+ * @licence GNU GPL v2+
+ * @author Thomas Pellissier Tanon < thoma...@hotmail.fr >
+ * @author Thibault Taillandier < thiba...@taillandier.name >
+ */
+class AncestorsFamilyTree extends FamilyTree
+{
+
+    /**
+     * List the ancestors of the person for all needed generations
+     *
+     * @return array the generations tree
+     */
+    public function getAncestors()
+    {
+        $tree = array();
+        $tree[0][1] = new PersonPageValues( $this->person );
+
+        for($i = 0; $i < $this->numOfGenerations && $tree[$i] !== null; $i++ ) 
{
+            $tree = $this->addGenInTree( $i + 1, $tree );
+        }
+        return $tree;
+    }
+
+
+    /**
+     * Render the tree of ancestors
+     *
+     * @return void
+     */
+    public function render()
+    {
+        $tree = $this->getAncestors();
+        $output = $this->getOutput();
+        $output->addHTML('<table style="text-align:center;">');
+        $col = 1;
+        for( $i = $this->numOfGenerations - 1; $i >= 0; $i-- ) {
+            if( isset( $tree[$i] ) ) {
+                $output->addHTML('<tr>');
+                foreach ($tree[$i] as $sosa => $person) {
+                    $output->addHTML('<td colspan="' . $col . '">');
+                    if($person !== null) {
+                        $output->addHTML($sosa . '<br/>' );
+                         $output->addWikiText( 
$person->getDescriptionWikiText( true ) );
+                        if($sosa != 1) {
+                            if($sosa % 2 == 0)
+                                $output->addHTML( '<br/>\\' );
+                            else
+                                $output->addHTML( '<br/>/' );
+                        }
+                    }
+                    $output->addHTML('</td>');
+                }
+                $output->addHTML('</tr>');
+            }
+            $col *= 2;
+        }
+        $output->addHTML('</table>');
+    }
+}
diff --git a/DescendantFamilyTree.php b/DescendantFamilyTree.php
new file mode 100644
index 0000000..ab60323
--- /dev/null
+++ b/DescendantFamilyTree.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * DescandantFamilyTree object
+ *
+ * Handle a FamilyTree to display the descendants of a person
+ * 
+ * @file DescendantFamilyTree.php
+ * @ingroup SemanticGenealogy
+ *
+ * @licence GNU GPL v2+
+ * @author Thomas Pellissier Tanon < thoma...@hotmail.fr >
+ * @author Thibault Taillandier < thiba...@taillandier.name >
+ */
+class DescendantFamilyTree extends FamilyTree
+{
+
+    /**
+     * List the descendants for all needed generations
+     *
+     * @return void
+     */
+    public function outputDescendantLine( $person, $pellissier, $end ) {
+        $output = $this->getOutput();
+        $children = $person->getChildren();
+        $i = 1;
+        foreach($children as $child) {
+            $pel = $pellissier . $i . '.';
+            $output->addWikiText( $pel . ' ' . $child->getDescriptionWikiText( 
false ) );
+            if( $end > 0 )
+                $this->outputDescendantLine( $child, $pel, $end - 1);
+            $i++;
+        }
+    }
+
+    /**
+     * Render the tree of descendants
+     *
+     * @return void
+     */
+    public function render()
+    {
+        $output = $this->getOutput();
+        $main = new PersonPageValues( $this->person );
+        $output->addWikiText( $main->getDescriptionWikiText( false ) );
+        $this->outputDescendantLine( $main, '', $this->numOfGenerations );
+    }
+}
diff --git a/FamilyTree.php b/FamilyTree.php
index 63ebb72..ed4d10a 100644
--- a/FamilyTree.php
+++ b/FamilyTree.php
@@ -1,234 +1,142 @@
 <?php
 
-
 /**
- * Special page that show a family tree
+ * FamilyTree object
+ *
+ * This class is abstract and cannot be instanciated. Please use the 
FamilyTreeFactory to create a specific type of FamilyTree (ancestors, 
descendant or relation)
  * 
- * @file SpecialFamilyTree.php
+ * @file    FamilyTree.php
  * @ingroup SemanticGenealogy
  *
  * @licence GNU GPL v2+
- * @author Thomas Pellissier Tanon < thoma...@hotmail.fr >
+ * @author  Thomas Pellissier Tanon <thoma...@hotmail.fr>
+ * @author  Thibault Taillandier <thiba...@taillandier.name>
  */
-class FamilyTree
+abstract class FamilyTree
 {
 
-    private $output;
+    protected $output;
+    protected $person;
+    protected $personName;
+    protected $numOfGenerations;
 
+    /**
+     * Setter for the person
+     * 
+     * @param string $personName the name of the page of the person
+     *
+     * @return void
+     */
+    public function setPerson($personName)
+    {
+        $this->personName = $personName;
+        $this->person = PersonPageValues::getPageFromName($personName);
+    }
 
+    /**
+     * Setter for the number of generations
+     * 
+     * @param integer $numOfGenerations the number of generations
+     *
+     * @return void
+     */
+    public function setNumberOfGenerations($numOfGenerations)
+    {
+        $this->numOfGenerations = $numOfGenerations;
+    }
+
+    /**
+     * Setter for the ouput object
+     * 
+     * @param OutputPage $output the output object
+     *
+     * @return void
+     */
     public function setOutput($output)
     {
         $this->output = $output;
     }
 
+    /**
+     * Getter for the ouput object
+     * 
+     * @return OutputPage the output object
+     */
     public function getOutput()
     {
         return $this->output;
     }
 
-       /**
-        * Return the number of people in a generation
-        *
-        * @param  int $gen The number of the generation (beginning at 0)
-        * @return int
-        */
-       public static function getNumOfPeopleInGen( $gen ) {
-               $result = 1;
-               for($i = 0; $i < $gen; $i++ ) {
-                       $result *= 2;
-               }
-               return $result;
-       }
-
-       public function getAncestors( SMWDIWikiPage $page, $numOfGenerations ) {
-               $tree = array();
-               $tree[0][1] = new PersonPageValues( $page );
-
-               for($i = 0; $i < $numOfGenerations && $tree[$i] !== null; $i++ 
) {
-                       $tree = $this->addGenInTree( $i + 1, $tree );
-               }
-               return $tree;
-       }
-
-       public function addGenInTree( $gen, array $tree ) {
-               $empty = true;
-               $son = self::getNumOfPeopleInGen( $gen - 1 );
-               $end = $son * 4;
-               for( $parent = $son * 2; $parent < $end; true ) {
-                       if( isset( $tree[$gen - 1][$son] ) ) {
-                               $father = $tree[$gen - 1][$son]->father;
-                               if( $father instanceof SMWDIWikiPage ) {
-                                       $tree[$gen][$parent] = new 
PersonPageValues( $father );
-                                       $empty = false;
-                               } else {
-                                       $tree[$gen][$parent] = null;
-                               }
-                               $parent++;
-
-                               $mother = $tree[$gen - 1][$son]->mother;
-                               if( $mother instanceof SMWDIWikiPage ) {
-                                       $tree[$gen][$parent] = new 
PersonPageValues( $mother );
-                                       $empty = false;
-                               } else {
-                                       $tree[$gen][$parent] = null;
-                               }
-                               $parent++;
-                       } else {
-                               $parent += 2;
-                       }
-                       $son++;
-               }
-               //Verif s'il n'y a personne dans la génération
-               if($empty) {
-                       $tree[$gen] = null;
-               }
-               return $tree;
-       }
-
-       public function outputAncestorsTree( array $tree, $numOfGenerations ) {
-               $output = $this->getOutput();
-               $output->addHTML('<table style="text-align:center;">');
-               $col = 1;
-               for( $i = $numOfGenerations - 1; $i >= 0; $i-- ) {
-                       if( isset( $tree[$i] ) ) {
-                               $output->addHTML('<tr>');
-                               foreach ($tree[$i] as $sosa => $person) {
-                                       $output->addHTML('<td colspan="' . $col 
. '">');
-                                       if($person !== null) {
-                                               $output->addHTML($sosa . 
'<br/>' );
-                                                $output->addWikiText( 
$person->getDescriptionWikiText( true ) );
-                                               if($sosa != 1) {
-                                                       if($sosa % 2 == 0)
-                                                               
$output->addHTML( '<br/>\\' );
-                                                       else
-                                                               
$output->addHTML( '<br/>/' );
-                                               }
-                                       }
-                                       $output->addHTML('</td>');
-                               }
-                               $output->addHTML('</tr>');
-                       }
-                       $col *= 2;
-               }
-               $output->addHTML('</table>');
-       }
-
-       public function outputDescendantList( SMWDIWikiPage $main, 
$numOfGenerations ) {
-               $output = $this->getOutput();
-               $main = new PersonPageValues( $main );
-               $output->addWikiText( $main->getDescriptionWikiText( false ) );
-               $this->outputDescendantLine( $main, '', $numOfGenerations );
-       }
-
-       public function outputDescendantLine( $person, $pellissier, $end ) {
-               $output = $this->getOutput();
-               $children = $person->getChildren();
-               $i = 1;
-               foreach($children as $child) {
-                       $pel = $pellissier . $i . '.';
-                       $output->addWikiText( $pel . ' ' . 
$child->getDescriptionWikiText( false ) );
-                       if( $end > 0 )
-                               $this->outputDescendantLine( $child, $pel, $end 
- 1);
-                       $i++;
-               }
-       }
-
-       public function getRelation( SMWDIWikiPage $page1, SMWDIWikiPage $page2 
) {
-               $tree1 = array();
-               $tree2 = array();
-               $tree1[0][1] = new PersonPageValues( $page1 );
-               $tree2[0][1] = new PersonPageValues( $page2 );
-
-               for($i = 0; $tree1[$i] !== null && $tree2[$i] !== null; $i++ ) {
-                       $tree1 = $this->addGenInTree( $i + 1, $tree1 );
-                       if($tree1[$i + 1] !== null) {
-                               $result = $this->compareGenWith($tree1[$i + 1], 
$tree2, $i );
-                               if($result !== null) {
-                                       list($sosa1, $sosa2) = $result;
-                                       break;
-                               }
-                       }
-
-                       $tree2 = $this->addGenInTree( $i + 1, $tree2 );
-                       if($tree2[$i + 1] !== null) {
-                               $result = $this->compareGenWith($tree2[$i + 1], 
$tree1, $i + 1 );
-                               if($result !== null) {
-                                       list($sosa2, $sosa1) = $result;
-                                       break;
-                               }
-                       }
-               }
-
-               if($result !== null)
-                       return array( $this->getListOfAncestors( $sosa1, $tree1 
), $this->getListOfAncestors( $sosa2, $tree2 ) );
-       }
-
-       public function compareGenWith( array $gen, array $tree, $max ) {
-               for( $i = $max; $i >= 0; $i-- ) {
-                       if( isset( $tree[$i] ) ) {
-                               foreach( $tree[$i] as $sosa2 => $person2 ) {
-                                       if($person2 !== null) {
-                                               foreach( $gen as $sosa1 => 
$person1 ) {
-                                                       if($person1 !== null) {
-                                                               if( 
$person1->title->equals( $person2->title ) ) {
-                                                                       return 
array( $sosa1, $sosa2 );
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       public function getListOfAncestors( $sosa, array $tree ) {
-               $num = 1;
-               $temp = 1;
-               for($i = 0; $num < $sosa; $i++) {
-                       $temp *= 2;
-                       $num += $temp;
-               }
-
-               $list = array();
-               for( $j = $i; $j >= 0; $j-- ) {
-                       $list[] = $tree[$j][$sosa];
-                       $sosa /= 2;
-               }
-               return $list;
-       }
-
-       public function outputRelationTree( array $trees ) {
-               $output = $this->getOutput();
-               list( $tree1, $tree2 ) = $trees;
-
-               $output->addHTML( '<table style="text-align:center;">' );
-               $output->addHTML( '<tr><td colspan="2">' );
-               $person = $tree1[0];
-               if( $person->fullname instanceof SMWDIBlob )
-                       $output->addWikiText( $person->getDescriptionWikiText( 
false ) );
-               $output->addHTML( '</td></tr>' );
-
-               $length = max( count( $tree1 ), count( $tree2 ) );
-               for($i = 1; $i < $length; $i++ ) {
-                       $output->addHTML('<tr><td>');
-                       if( isset( $tree1[$i] ) ) {
-                               $person = $tree1[$i];
-                               if( $person->fullname instanceof SMWDIBlob )
-                                       $output->addWikiText( '|<br/>' . 
$person->getDescriptionWikiText( false ) );
-                       }
-                       $output->addHTML('</td><td>');
-                       if( isset( $tree2[$i] ) ) {
-                               $person = $tree2[$i];
-                               if( $person->fullname instanceof SMWDIBlob )
-                                       $output->addWikiText( '|<br/>' . 
$person->getDescriptionWikiText( false ) );
-                       }
-                       $output->addHTML('</td></tr>');
-               }
-               $output->addHTML('</table>');
-       }
+    /**
+     * Return the number of people in a generation
+     *
+     * @param  int $gen The number of the generation (beginning at 0)
+     * @return int
+     */
+    public static function getNumOfPeopleInGen( $gen )
+    {
+        $result = 1;
+        for($i = 0; $i < $gen; $i++ ) {
+            $result *= 2;
+        }
+        return $result;
+    }
 
 
+    /**
+     * Add a generation in a tree
+     *
+     * @param integer $gen the generation number
+     * @param array   $tree the tree to add in
+     *
+     * @return array the resulting tree
+     */
+    public function addGenInTree( $gen, array $tree )
+    {
+        $empty = true;
+        $son = self::getNumOfPeopleInGen( $gen - 1 );
+        $end = $son * 4;
+        for( $parent = $son * 2; $parent < $end; true ) {
+            if( isset( $tree[$gen - 1][$son] ) ) {
+                $father = $tree[$gen - 1][$son]->father;
+                if( $father instanceof SMWDIWikiPage ) {
+                    $tree[$gen][$parent] = new PersonPageValues( $father );
+                    $empty = false;
+                } else {
+                    $tree[$gen][$parent] = null;
+                }
+                $parent++;
+
+                $mother = $tree[$gen - 1][$son]->mother;
+                if( $mother instanceof SMWDIWikiPage ) {
+                    $tree[$gen][$parent] = new PersonPageValues( $mother );
+                    $empty = false;
+                } else {
+                    $tree[$gen][$parent] = null;
+                }
+                $parent++;
+            } else {
+                $parent += 2;
+            }
+            $son++;
+        }
+        //Verif s'il n'y a personne dans la génération
+        if($empty) {
+            $tree[$gen] = null;
+        }
+        return $tree;
+    }
 
 
-
+    /**
+     * Render the tree
+     *
+     * This should not be used, because you should not use a abstract 
FamilyTree
+     * 
+     * @return void
+     */
+    public function render()
+    {
+        $output->addHtml("");
+    }
 }
diff --git a/FamilyTreeFactory.php b/FamilyTreeFactory.php
new file mode 100644
index 0000000..0fcdbf1
--- /dev/null
+++ b/FamilyTreeFactory.php
@@ -0,0 +1,24 @@
+<?php
+
+
+class FamilyTreeFactory
+{
+
+       public static function create($type)
+       {
+               switch($type) {
+                       case 'ancestors':
+                               return new AncestorsFamilyTree();
+                               break;
+                       case 'descendant':
+                               return new DescendantFamilyTree();
+                               break;
+                       case 'link':
+                               return new RelationFamilyTree();
+                               break;
+                       default:
+                               $output->addWikiText( '<span class="error">' . 
wfMsg( 'semanticgenealogy-specialfamilytree-error-unknowntype', $type ) . 
'</span>' );
+               }
+
+       }
+}
diff --git a/FamilyTreeTag.php b/FamilyTreeTag.php
index 2c7dc41..2b4b66b 100644
--- a/FamilyTreeTag.php
+++ b/FamilyTreeTag.php
@@ -1,6 +1,16 @@
 <?php
 
-
+/**
+ * FamilyTreeTag objecta
+ *
+ * Handle the <familytree> tag using a FamilyTree object
+ * 
+ * @file FamilyTreeTag.php
+ * @ingroup SemanticGenealogy
+ *
+ * @licence GNU GPL v2+
+ * @author Thibault Taillandier < thiba...@taillandier.name >
+ */
 class FamilyTreeTag
 {
 
@@ -9,7 +19,6 @@
     const ATTR_PERSON2 = "person2";
     const ATTR_DEPTH = "depth";
     const ATTR_TYPE = "type";
-    const ATTR_STYLE = "style";
 
     // Hook our callback function into the parser
     public static function wfFamilytreeParserInit (Parser $parser)
@@ -20,44 +29,32 @@
         return true;
     }
 
-    // Execute 
+    /**
+     * Render the family tree
+     * 
+     * @param string  $input  the content of the <familytree /> tag (should be 
empty)
+     * @param array   $args   the arguments
+     * @param Parser  $parser None
+     * @param PPFrame $frame  None
+     *
+     * @return the HTML output of the tree
+     */
     public static function wfFamilytreeRender ($input, array $args, Parser 
$parser, PPFrame $frame)
     {
+        // A new OutputPage writer
         $output = new OutputPage;
-        $familytree = new FamilyTree();
+        $familytree = FamilyTreeFactory::create($args[self::ATTR_TYPE]);
         $familytree->setOutput($output);
-        $numOfGenerations = $args[self::ATTR_DEPTH];
-        $pageName = $args[self::ATTR_PERSON];
-               $pageTitle = Title::newFromText( $pageName );
-        $page = SMWDIWikiPage::newFromTitle( $pageTitle );
+        $familytree->setPerson($args[self::ATTR_PERSON]);
+        $familytree->setNumberOfGenerations($args[self::ATTR_DEPTH]);
 
-
-               switch($args[self::ATTR_TYPE]) {
-                       case 'ancestors':
-                               $tree = $familytree->getAncestors( $page, 
$numOfGenerations );
-                               $familytree->outputAncestorsTree( $tree, 
$numOfGenerations );
-                               break;
-                       case 'descendant':
-                               $familytree->outputDescendantList( $page, 
$numOfGenerations );
-                               break;
-                       case 'link':
-                               if($pageName2 == '') {
-                                       $output->addWikiText( '<span 
class="error">' . wfMsg( 
'semanticgenealogy-specialfamilytree-error-nosecondpagename' ) . '</span>' );
-                                       return;
-                               }
-                               $pageTitle2 = Title::newFromText( $pageName2 );
-                               $page2 = SMWDIWikiPage::newFromTitle( 
$pageTitle2 );
-                               $tree = $familytree->getRelation( $page, $page2 
);
-                               if( $tree !== null) {
-                                       $familytree->outputRelationTree( $tree 
);
-                               } else {
-                                       $output->addWikiText( '<span 
class="error">' . wfMsg( 
'semanticgenealogy-specialfamilytree-error-nolinkfound', $pageName, $pageName2 
) . '</span>' );
-                               }
-                               break;
-                       default:
-                $output->addWikiText( '<span class="error">' . wfMsg( 
'semanticgenealogy-specialfamilytree-error-unknowntype', $type ) . '</span>' );
+        $personName2 = $args[self::ATTR_PERSON2];
+        if ($personName2) {
+            $familytree->setPerson2($personName2);
         }
 
+        $familytree->render();
+
         $output->setArticleBodyOnly(true);
         ob_start();
         $output->output();
diff --git a/PersonPageValues.php b/PersonPageValues.php
index de3a7e8..b37ad6b 100644
--- a/PersonPageValues.php
+++ b/PersonPageValues.php
@@ -130,5 +130,11 @@
                $val = new SMWTimeValue( SMWDataItem::TYPE_TIME );
                $val->setDataItem( $di );
                return $val->getShortWikiText();
-       }
+    }
+
+    public static function getPageFromName($pageName)
+    {
+               $pageTitle = Title::newFromText($pageName);
+        return SMWDIWikiPage::newFromTitle($pageTitle);
+    }
 }
diff --git a/RelationFamilyTree.php b/RelationFamilyTree.php
new file mode 100644
index 0000000..1bc9490
--- /dev/null
+++ b/RelationFamilyTree.php
@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * RelationFamilyTree object
+ *
+ * Handle a FamilyTree to display the relationship between 2 persons.
+ * Find the closest common ancestor
+ * 
+ * @file RelationFamilyTree.php
+ * @ingroup SemanticGenealogy
+ *
+ * @licence GNU GPL v2+
+ * @author Thomas Pellissier Tanon < thoma...@hotmail.fr >
+ * @author Thibault Taillandier < thiba...@taillandier.name >
+ */
+class RelationFamilyTree extends FamilyTree
+{
+
+    protected $person2;
+    protected $personName2;
+
+    /**
+     * Setter of person2
+     *
+     * @param string $personName2 the page name of the person
+     *
+     * @see PersonPageValues::getPageFromName
+     * 
+     * @return void
+     */
+    public function setPerson2($personName2)
+    {
+        $this->personName2 = $personName2;
+        $this->person2 = PersonPageValues::getPageFromName($personName2);
+    }
+
+
+    /**
+     * Get the relation between the 2 persons (this->person and $this->person2)
+     * 
+     * @return array an array of 2 trees
+     */
+    public function getRelation()
+    {
+        $tree1 = array();
+        $tree2 = array();
+        $tree1[0][1] = new PersonPageValues( $this->person );
+        $tree2[0][1] = new PersonPageValues( $this->person2 );
+
+        for($i = 0; $tree1[$i] !== null && $tree2[$i] !== null; $i++ ) {
+            $tree1 = $this->addGenInTree( $i + 1, $tree1 );
+            if($tree1[$i + 1] !== null) {
+                $result = $this->compareGenWith($tree1[$i + 1], $tree2, $i );
+                if($result !== null) {
+                    list($sosa1, $sosa2) = $result;
+                    break;
+                }
+            }
+
+            $tree2 = $this->addGenInTree( $i + 1, $tree2 );
+            if($tree2[$i + 1] !== null) {
+                $result = $this->compareGenWith($tree2[$i + 1], $tree1, $i + 1 
);
+                if($result !== null) {
+                    list($sosa2, $sosa1) = $result;
+                    break;
+                }
+            }
+        }
+
+        if($result !== null)
+            return array( $this->getListOfAncestors( $sosa1, $tree1 ), 
$this->getListOfAncestors( $sosa2, $tree2 ) );
+    }
+
+    /**
+     * Compare a generation with a tree
+     * 
+     * @param array $gen
+     * @param array $tree the tree
+     * @param integer $max the max depth
+     *
+     * @return array an array of 2 SOSA
+     */
+    public function compareGenWith( array $gen, array $tree, $max ) {
+        for( $i = $max; $i >= 0; $i-- ) {
+            if( isset( $tree[$i] ) ) {
+                foreach( $tree[$i] as $sosa2 => $person2 ) {
+                    if($person2 !== null) {
+                        foreach( $gen as $sosa1 => $person1 ) {
+                            if($person1 !== null) {
+                                if( $person1->title->equals( $person2->title ) 
) {
+                                    return array( $sosa1, $sosa2 );
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Get the list of ancestors for a sosa number
+     * 
+     * @param integer $sosa the SOSA number
+     * @param array   $tree
+     *
+     * @return array the list of ancestors
+     */
+    public function getListOfAncestors( $sosa, array $tree ) {
+        $num = 1;
+        $temp = 1;
+        for($i = 0; $num < $sosa; $i++) {
+            $temp *= 2;
+            $num += $temp;
+        }
+
+        $list = array();
+        for( $j = $i; $j >= 0; $j-- ) {
+            $list[] = $tree[$j][$sosa];
+            $sosa /= 2;
+        }
+        return $list;
+    }
+
+    /**
+     * Render the tree
+     *
+     * @return void
+     */
+    public function render()
+    {
+        $output = $this->getOutput();
+        $tree = $this->getRelation();
+        if (!$tree)
+        {
+            $output->addWikiText( '<span class="error">' . wfMsg( 
'semanticgenealogy-specialfamilytree-error-nolinkfound', $this->personName, 
$this->personName2 ) . '</span>' );
+            return;
+        }
+        list($tree1, $tree2) = $tree;
+
+        $output->addHTML( '<table style="text-align:center;">' );
+        $output->addHTML( '<tr><td colspan="2">' );
+        $person = $tree1[0];
+        if( $person->fullname instanceof SMWDIBlob )
+            $output->addWikiText( $person->getDescriptionWikiText( false ) );
+        $output->addHTML( '</td></tr>' );
+
+        $length = max( count( $tree1 ), count( $tree2 ) );
+        for($i = 1; $i < $length; $i++ ) {
+            $output->addHTML('<tr><td>');
+            if( isset( $tree1[$i] ) ) {
+                $person = $tree1[$i];
+                if( $person->fullname instanceof SMWDIBlob )
+                    $output->addWikiText( '|<br/>' . 
$person->getDescriptionWikiText( false ) );
+            }
+            $output->addHTML('</td><td>');
+            if( isset( $tree2[$i] ) ) {
+                $person = $tree2[$i];
+                if( $person->fullname instanceof SMWDIBlob )
+                    $output->addWikiText( '|<br/>' . 
$person->getDescriptionWikiText( false ) );
+            }
+            $output->addHTML('</td></tr>');
+        }
+        $output->addHTML('</table>');
+    }
+}
diff --git a/SemanticGenealogy.php b/SemanticGenealogy.php
index f30f429..9ce5a0d 100644
--- a/SemanticGenealogy.php
+++ b/SemanticGenealogy.php
@@ -72,6 +72,10 @@
 $wgAutoloadClasses['PersonPageValues'] = $dir . 'PersonPageValues.php';
 $wgAutoloadClasses['FamilyTreeTag'] = $dir . 'FamilyTreeTag.php';
 $wgAutoloadClasses['FamilyTree'] = $dir . 'FamilyTree.php';
+$wgAutoloadClasses['AncestorsFamilyTree'] = $dir . 'AncestorsFamilyTree.php';
+$wgAutoloadClasses['DescendantFamilyTree'] = $dir . 'DescendantFamilyTree.php';
+$wgAutoloadClasses['RelationFamilyTree'] = $dir . 'RelationFamilyTree.php';
+$wgAutoloadClasses['FamilyTreeFactory'] = $dir . 'FamilyTreeFactory.php';
 
 $wgAutoloadClasses['GenealogicalFilePrinter'] = $dir . 
'GenealogicalFilePrinter.php';
 $wgAutoloadClasses['Gedcom5FilePrinter'] = $dir . 
'GenealogicalFilePrinter.php';
diff --git a/SpecialFamilyTree.php b/SpecialFamilyTree.php
index 1fb3019..90b19b4 100644
--- a/SpecialFamilyTree.php
+++ b/SpecialFamilyTree.php
@@ -9,142 +9,154 @@
  * @licence GNU GPL v2+
  * @author Thomas Pellissier Tanon < thoma...@hotmail.fr >
  */
-class SpecialFamilyTree extends SpecialPage {
+class SpecialFamilyTree extends SpecialPage
+{
 
-       public function __construct( $name = 'FamilyTree' ) {
-               parent::__construct( $name, 'other' );
-               $this->mIncludable = true;
-       }
+    /**
+     * @constructor
+     *
+     * @param string $name the name of the SpecialPage
+     *
+     * @return void
+     */
+    public function __construct( $name = 'FamilyTree' )
+    {
+        parent::__construct( $name, 'other' );
+        $this->mIncludable = true;
+    }
 
-       public function execute( $par ) {
-               global $wgRequest, $wgScript;
+    /**
+     * Execute the Special Page
+     *
+     * @param string $par the url part
+     *
+     * @return boolean the status of the rendered page
+     */
+    public function execute( $par )
+    {
+        global $wgRequest, $wgScript;
 
-               $this->setHeaders();
-               $output = $this->getOutput();
+        $this->setHeaders();
+        $output = $this->getOutput();
 
-               if( $par != '') {
-                       $parts = explode('/', urldecode( $par ));
-               } else {
-                       $parts = array();
-               }
+        if( $par != '') {
+            $parts = explode('/', urldecode( $par ));
+        } else {
+            $parts = array();
+        }
 
-               $type = isset( $parts[0] ) ? $parts[0] : $wgRequest->getText( 
'type' );
-               if($type == '') {
-                       $type = 'ancestors';
-               }
+        $type = isset( $parts[0] ) ? $parts[0] : $wgRequest->getText( 'type' );
+        if($type == '') {
+            $type = 'ancestors';
+        }
 
-               $pageName = isset( $parts[1] ) ? $parts[1] : 
$wgRequest->getText( 'page' );
+        $pageName = isset( $parts[1] ) ? $parts[1] : $wgRequest->getText( 
'page' );
 
-               if( $type == 'link' ) {
-                       $pageName2 = isset( $parts[2] ) ? $parts[2] : 
$wgRequest->getText( 'page2' );
-                       $numOfGenerations = 0;
-               } else {
-                       $numOfGenerations = isset( $parts[2] ) ? intval( 
$parts[2] ) : $wgRequest->getInt( 'gen' );
-                       if($numOfGenerations <= 0) {
-                               $numOfGenerations = 5;
-                       }
-                       $pageName2 = '';
-               }
+        if( $type == 'link' ) {
+            $pageName2 = isset( $parts[2] ) ? $parts[2] : $wgRequest->getText( 
'page2' );
+            $numOfGenerations = 0;
+        } else {
+            $numOfGenerations = isset( $parts[2] ) ? intval( $parts[2] ) : 
$wgRequest->getInt( 'gen' );
+            if($numOfGenerations <= 0) {
+                $numOfGenerations = 5;
+            }
+            $pageName2 = '';
+        }
 
-               if( !$this->mIncluding ) {
-                       $output->addModules( 'ext.smg.specialfamilytree' );
-                       $typeSelect = new XmlSelect( 'type', 'type', $type );
-                       $typeSelect->addOption( wfMsg( 
'semanticgenealogy-specialfamilytree-type-ancestors' ), 'ancestors' );
-                       $typeSelect->addOption( wfMsg( 
'semanticgenealogy-specialfamilytree-type-descendant' ), 'descendant' );
-                       $typeSelect->addOption( wfMsg( 
'semanticgenealogy-specialfamilytree-type-link' ), 'link' );
-                       $output->addHTML(
-                               Xml::openElement( 'form', array( 'action' => 
$wgScript ) ) .
-                                       Html::hidden( 'title', 
$this->getPageTitle()->getPrefixedText() ) .
-                                       Xml::openElement( 'fieldset' ) .
-                                               Xml::openElement( 'table', 
array( 'id' => 'smg-familyTree-form' ) ) .
-                                                       Xml::openElement( 'tr', 
array('id' => 'smg-form-entry-page' ) ) .
-                                                               
Xml::openElement( 'th', array('class' => 'mw-label') ) .
-                                                                       
Xml::label( wfMsg( 'semanticgenealogy-specialfamilytree-label-page' ), 'page' ) 
.
-                                                               
Xml::closeElement( 'th' ) .
-                                                               
Xml::openElement( 'td', array('class' => 'mw-input') ) .
-                                                                       
Xml::input( 'page', 30, $pageName, array( 'class' => 'smg-input-page' ) ) .
-                                                               
Xml::closeElement( 'td' ) .
-                                                       Xml::closeElement( 'tr' 
) .
-                                                       Xml::openElement( 'tr', 
array('id' => 'smg-form-entry-type' ) ) .
-                                                               
Xml::openElement( 'th', array('class' => 'mw-label') ) .
-                                                                       
Xml::label( wfMsg( 'semanticgenealogy-specialfamilytree-label-type' ), 'type' ) 
.
-                                                               
Xml::closeElement( 'th' ) .
-                                                               
Xml::openElement( 'td', array('class' => 'mw-input') ) .
-                                                                       
$typeSelect->getHtml() .
-                                                               
Xml::closeElement( 'td' ) .
-                                                       Xml::closeElement( 'tr' 
) .
-                                                       Xml::openElement( 'tr', 
array('id' => 'smg-form-entry-gen' ) ) .
-                                                               
Xml::openElement( 'th', array('class' => 'mw-label') ) .
-                                                                       
Xml::label( wfMsg( 'semanticgenealogy-specialfamilytree-label-gen' ), 'gen' ) .
-                                                               
Xml::closeElement( 'th' ) .
-                                                               
Xml::openElement( 'td', array('class' => 'mw-input') ) .
-                                                                       
Xml::input( 'gen', 2, $numOfGenerations ) .
-                                                               
Xml::closeElement( 'td' ) .
-                                                       Xml::closeElement( 'tr' 
) .
-                                                       Xml::openElement( 'tr', 
array('id' => 'smg-form-entry-page2' ) ) .
-                                                               
Xml::openElement( 'th', array('class' => 'mw-label') ) .
-                                                                       
Xml::label( wfMsg( 'semanticgenealogy-specialfamilytree-label-page2' ), 'page2' 
) .
-                                                               
Xml::closeElement( 'th' ) .
-                                                               
Xml::openElement( 'td', array('class' => 'mw-input') ) .
-                                                                       
Xml::input( 'page2', 30, $pageName2, array( 'class' => 'smg-input-page' ) ) .
-                                                               
Xml::closeElement( 'td' ) .
-                                                       Xml::closeElement( 'tr' 
) .
-                                               Xml::closeElement( 'table' ) .
-                                               Xml::submitButton( wfMsg( 
'semanticgenealogy-specialfamilytree-button-submit' ) ) .
-                                       Xml::closeElement( 'fieldset' ) .
-                               Xml::closeElement( 'form' )
-                       );
-               }
+        if( !$this->mIncluding ) {
+            $output->addModules( 'ext.smg.specialfamilytree' );
+            $typeSelect = new XmlSelect( 'type', 'type', $type );
+            $typeSelect->addOption( wfMsg( 
'semanticgenealogy-specialfamilytree-type-ancestors' ), 'ancestors' );
+            $typeSelect->addOption( wfMsg( 
'semanticgenealogy-specialfamilytree-type-descendant' ), 'descendant' );
+            $typeSelect->addOption( wfMsg( 
'semanticgenealogy-specialfamilytree-type-link' ), 'link' );
+            $output->addHTML(
+                Xml::openElement( 'form', array( 'action' => $wgScript ) ) .
+                    Html::hidden( 'title', 
$this->getPageTitle()->getPrefixedText() ) .
+                    Xml::openElement( 'fieldset' ) .
+                        Xml::openElement( 'table', array( 'id' => 
'smg-familyTree-form' ) ) .
+                            Xml::openElement( 'tr', array('id' => 
'smg-form-entry-page' ) ) .
+                                Xml::openElement( 'th', array('class' => 
'mw-label') ) .
+                                    Xml::label( wfMsg( 
'semanticgenealogy-specialfamilytree-label-page' ), 'page' ) .
+                                Xml::closeElement( 'th' ) .
+                                Xml::openElement( 'td', array('class' => 
'mw-input') ) .
+                                    Xml::input( 'page', 30, $pageName, array( 
'class' => 'smg-input-page' ) ) .
+                                Xml::closeElement( 'td' ) .
+                            Xml::closeElement( 'tr' ) .
+                            Xml::openElement( 'tr', array('id' => 
'smg-form-entry-type' ) ) .
+                                Xml::openElement( 'th', array('class' => 
'mw-label') ) .
+                                    Xml::label( wfMsg( 
'semanticgenealogy-specialfamilytree-label-type' ), 'type' ) .
+                                Xml::closeElement( 'th' ) .
+                                Xml::openElement( 'td', array('class' => 
'mw-input') ) .
+                                    $typeSelect->getHtml() .
+                                Xml::closeElement( 'td' ) .
+                            Xml::closeElement( 'tr' ) .
+                            Xml::openElement( 'tr', array('id' => 
'smg-form-entry-gen' ) ) .
+                                Xml::openElement( 'th', array('class' => 
'mw-label') ) .
+                                    Xml::label( wfMsg( 
'semanticgenealogy-specialfamilytree-label-gen' ), 'gen' ) .
+                                Xml::closeElement( 'th' ) .
+                                Xml::openElement( 'td', array('class' => 
'mw-input') ) .
+                                    Xml::input( 'gen', 2, $numOfGenerations ) .
+                                Xml::closeElement( 'td' ) .
+                            Xml::closeElement( 'tr' ) .
+                            Xml::openElement( 'tr', array('id' => 
'smg-form-entry-page2' ) ) .
+                                Xml::openElement( 'th', array('class' => 
'mw-label') ) .
+                                    Xml::label( wfMsg( 
'semanticgenealogy-specialfamilytree-label-page2' ), 'page2' ) .
+                                Xml::closeElement( 'th' ) .
+                                Xml::openElement( 'td', array('class' => 
'mw-input') ) .
+                                    Xml::input( 'page2', 30, $pageName2, 
array( 'class' => 'smg-input-page' ) ) .
+                                Xml::closeElement( 'td' ) .
+                            Xml::closeElement( 'tr' ) .
+                        Xml::closeElement( 'table' ) .
+                        Xml::submitButton( wfMsg( 
'semanticgenealogy-specialfamilytree-button-submit' ) ) .
+                    Xml::closeElement( 'fieldset' ) .
+                Xml::closeElement( 'form' )
+            );
+        }
 
-               if( $pageName == '')
-                       return;
+        if( $pageName == '') {
+            return;
+        }
 
-               $pageTitle = Title::newFromText( $pageName );
-        $page = SMWDIWikiPage::newFromTitle( $pageTitle );
 
-        $familytree = new FamilyTree();
+        $familytree = FamilyTreeFactory::create($type);
+        $familytree->setPerson($pageName);
+
+        if ($pageName2) {
+            $familytree->setPerson2($pageName2);
+        }
+
         $familytree->setOutput($this->getOutput());
+        $familytree->setNumberOfGenerations($numOfGenerations);
 
-               if($type == '')
-                       $type = 'ancestors';
-               switch($type) {
-                       case 'ancestors':
-                               $tree = $familytree->getAncestors( $page, 
$numOfGenerations );
-                               $familytree->outputAncestorsTree( $tree, 
$numOfGenerations );
-                               break;
-                       case 'descendant':
-                               $familytree->outputDescendantList( $page, 
$numOfGenerations );
-                               break;
-                       case 'link':
-                               if($pageName2 == '') {
-                                       $output->addWikiText( '<span 
class="error">' . wfMsg( 
'semanticgenealogy-specialfamilytree-error-nosecondpagename' ) . '</span>' );
-                                       return;
-                               }
-                               $pageTitle2 = Title::newFromText( $pageName2 );
-                               $page2 = SMWDIWikiPage::newFromTitle( 
$pageTitle2 );
-                               $tree = $familytree->getRelation( $page, $page2 
);
-                               if( $tree !== null) {
-                                       $familytree->outputRelationTree( $tree 
);
-                               } else {
-                                       $output->addWikiText( '<span 
class="error">' . wfMsg( 
'semanticgenealogy-specialfamilytree-error-nolinkfound', $pageName, $pageName2 
) . '</span>' );
-                               }
-                               break;
-                       default:
-                               $output->addWikiText( '<span class="error">' . 
wfMsg( 'semanticgenealogy-specialfamilytree-error-unknowntype', $type ) . 
'</span>' );
-               }
-               return Status::newGood();
-       }
+        $familytree->render();
+        return Status::newGood();
+    }
 
-       public function isCacheable() {
-               return false;
-       }
+    /**
+     * Wether the page is cachable
+     *
+     * @return boolean
+     */
+    public function isCacheable() {
+        return false;
+    }
 
-       public function getDescription( ) {
-               return wfMsg( 'semanticgenealogy-specialfamilytree-title' );
-       }
+    /**
+     * Get the description
+     *
+     * @return string
+     */
+    public function getDescription( ) {
+        return wfMsg( 'semanticgenealogy-specialfamilytree-title' );
+    }
 
 
-       protected function getGroupName() {
-               return 'other';
-       }
+    /**
+     * Get the groupe name
+     *
+     * @return string
+     */
+    protected function getGroupName() {
+        return 'other';
+    }
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/245905
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I02693b0020e2e111e3f39b94ee4f5e8530f8127e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/SemanticGenealogy
Gerrit-Branch: master
Gerrit-Owner: Wilkins <thiba...@taillandier.name>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to