Source for file jDaoParser.class.php

Documentation is available at jDaoParser.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  dao
  5. @author      GĂ©rald Croes, Laurent Jouanneau
  6. @contributor Laurent Jouanneau
  7. @copyright   2001-2005 CopixTeam, 2005-2012 Laurent Jouanneau
  8. *  This class was get originally from the Copix project (CopixDAODefinitionV1, Copix 2.3dev20050901, http://www.copix.org)
  9. *  Few lines of code are still copyrighted 2001-2005 CopixTeam (LGPL licence).
  10. *  Initial authors of this Copix class are Gerald Croes and Laurent Jouanneau,
  11. *
  12. @link        http://www.jelix.org
  13. @licence  http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  14. */
  15.  
  16. require(JELIX_LIB_PATH.'dao/jDaoXmlException.class.php');
  17. require(JELIX_LIB_PATH.'dao/jDaoProperty.class.php');
  18. require(JELIX_LIB_PATH.'dao/jDaoMethod.class.php');
  19. require(JELIX_LIB_PATH.'dao/jDaoGenerator.class.php');
  20.  
  21. /**
  22.  * extract data from a dao xml content
  23.  * @package  jelix
  24.  * @subpackage dao
  25.  * @see jDaoCompiler
  26.  */
  27. class jDaoParser {
  28.     /**
  29.     * the properties list.
  30.     * keys = field code name
  31.     * values = jDaoProperty
  32.     */
  33.     private $_properties array ();
  34.  
  35.     /**
  36.     * all tables with their properties, and their own fields
  37.     * keys = table code name
  38.     * values = array()
  39.     *          'name'=> table code name, 'realname'=>'real table name',
  40.     *           'pk'=> primary keys list
  41.     *          'fk'=> foreign keys list
  42.     *          'fields'=>array(list of field code name)
  43.     */
  44.     private $_tables array();
  45.  
  46.     /**
  47.     * primary table code name
  48.     */
  49.     private $_primaryTable '';
  50.  
  51.     /**
  52.     * code name of foreign table with a outer join
  53.     * @var array  list of array(table code name, 0)
  54.     */
  55.     private $_ojoins array ();
  56.  
  57.     /**
  58.     * code name of foreign table with a inner join
  59.     * @var array  list of table code name
  60.     */
  61.     private $_ijoins array ();
  62.  
  63.     /**
  64.      * @var array list of jDaoMethod objects
  65.      */
  66.     private $_methods array();
  67.  
  68.     /**
  69.      * list of main events to sent
  70.      */
  71.     private $_eventList array();
  72.  
  73.     public $hasOnlyPrimaryKeys = false;
  74.  
  75.     /**
  76.      * selector of the user record class
  77.      * @var jSelectorDaoRecord 
  78.      */
  79.     private $_userRecord null;
  80.     
  81.     /**
  82.      * selector of the imported dao
  83.      * @var jSelectorDao[] 
  84.      */
  85.     private $_importedDao null;
  86.     
  87.     public $selector;
  88.     /**
  89.     * Constructor
  90.     */
  91.     function __construct($selector{
  92.         $this->selector = $selector;
  93.     }
  94.  
  95.     /**
  96.     * parse a dao xml content
  97.     * @param SimpleXmlElement $xml 
  98.     * @param jDbTools $tools 
  99.     * @param int $debug  for debug only 0:parse all, 1:parse only datasource+record, 2;parse only datasource
  100.     */
  101.     public function parse ($xml$tools{
  102.         $this->import($xml$tools);
  103.         $this->parseDatasource($xml);
  104.         $this->parseRecord($xml$tools);
  105.         $this->parseFactory($xml);
  106.     }
  107.     
  108.     protected function import ($xml$tools{
  109.         if (isset($xml['import'])) {
  110.             $import = (string)$xml['import'];
  111.  
  112.             jApp::pushCurrentModule($this->selector->module);
  113.             // Keep the same driver as current used
  114.             $importSel new jSelectorDao($import$this->selector->driver);
  115.             jApp::popCurrentModule();
  116.  
  117.             $doc new DOMDocument();
  118.             if (!$doc->load($importSel->getPath())) {
  119.                 throw new jException('jelix~daoxml.file.unknown'$importSel->getPath());
  120.             }
  121.             $parser new jDaoParser ($importSel);
  122.             $parser->parse(simplexml_import_dom($doc)$tools);
  123.  
  124.             $this->_properties $parser->getProperties();
  125.             $this->_tables $parser->getTables();
  126.             $this->_primaryTable $parser->getPrimaryTable();
  127.             $this->_methods $parser->getMethods();
  128.             $this->_ojoins $parser->getOuterJoins();
  129.             $this->_ijoins $parser->getInnerJoins();
  130.             $this->_eventList $parser->getEvents();
  131.             $this->_userRecord $parser->getUserRecord();
  132.             $this->_importedDao $parser->getImportedDao();
  133.             $this->hasOnlyPrimaryKeys = $parser->hasOnlyPrimaryKeys;
  134.  
  135.             if ($this->_importedDao)
  136.                 $this->_importedDao[$importSel;
  137.             else
  138.                 $this->_importedDao array($importSel);
  139.         }
  140.     }
  141.     
  142.     protected function parseDatasource($xml{
  143.         // -- tables
  144.         if(isset ($xml->datasources&& isset ($xml->datasources[0]->primarytable)) {
  145.             $previousTables $this->_tables;
  146.             // erase table definitions (in the case where the dao imports an other one)
  147.             $this->_tables array();
  148.             $this->_ijoins array();
  149.             $this->_ojoins array();
  150.  
  151.             $t $this->_parseTable (0$xml->datasources[0]->primarytable[0]);
  152.             $this->_primaryTable $t['name'];
  153.             if (isset($previousTables[$t['name']])) {
  154.                 $this->_tables[$t['name']]['fields'$previousTables[$t['name']]['fields'];
  155.             }
  156.             if(isset($xml->datasources[0]->primarytable[1])){
  157.                 throw new jDaoXmlException ($this->selector'table.two.many');
  158.             }
  159.             foreach($xml->datasources[0]->foreigntable as $table){
  160.                 $t $this->_parseTable (1$table);
  161.                 if (isset($previousTables[$t['name']])) {
  162.                     $this->_tables[$t['name']]['fields'$previousTables[$t['name']]['fields'];
  163.                 }
  164.             }
  165.             foreach($xml->datasources[0]->optionalforeigntable as $table){
  166.                 $t $this->_parseTable (2$table);
  167.                 if (isset($previousTables[$t['name']])) {
  168.                     $this->_tables[$t['name']]['fields'$previousTables[$t['name']]['fields'];
  169.                 }
  170.             }
  171.         }else if ($this->_primaryTable === ''// no imported dao
  172.             throw new jDaoXmlException ($this->selector'datasource.missing');
  173.         }
  174.     }
  175.     
  176.     protected function parseRecord($xml$tools{
  177.  
  178.         //add the record properties
  179.         if(isset($xml->record)){
  180.             if (isset($xml->record[0]['extends'])) {
  181.                 jApp::pushCurrentModule($this->selector->module);
  182.                 $this->_userRecord new jSelectorDaoRecord((string)$xml->record[0]['extends']);
  183.                 jApp::popCurrentModule();
  184.             }
  185.             if (isset($xml->record[0]->property)) {
  186.                 // don't append directly new properties into _properties,
  187.                 // so we can see the differences between imported properties
  188.                 // and readed properties
  189.                 $properties array();
  190.                 foreach ($xml->record[0]->property as $prop){
  191.                     $p new jDaoProperty ($prop->attributes()$this$tools);
  192.                     if (isset($properties[$p->name])) {
  193.                         throw new jDaoXmlException ($this->selector'property.already.defined'$p->name);
  194.                     }
  195.                     if (!in_array($p->name$this->_tables[$p->table]['fields'])) // if this property does not redefined an imported property
  196.                         $this->_tables[$p->table]['fields'][$p->name;
  197.                     }
  198.                     $properties[$p->name$p;
  199.                 }
  200.                 $this->_properties array_merge($this->_properties$properties);
  201.             }
  202.         }
  203.         // in the case when there is no defined property and no imported dao
  204.         if (count($this->_properties== 0)
  205.             throw new jDaoXmlException ($this->selector'properties.missing');
  206.  
  207.         // check that properties are attached to a known table. It can be
  208.         // wrong if the datasource has been redefined with other table names
  209.         $countprop 0;
  210.         foreach ($this->_properties as $p{
  211.             if (!isset($this->_tables[$p->table]))
  212.                 throw new jDaoXmlException ($this->selector'property.imported.unknown.table'$p->name);
  213.             if($p->ofPrimaryTable && !$p->isPK)
  214.                 $countprop ++;
  215.         }
  216.         $this->hasOnlyPrimaryKeys = ($countprop == 0);
  217.     }
  218.  
  219.     protected function parseFactory($xml{
  220.         // get additionnal methods definition
  221.         if (isset ($xml->factory)) {
  222.             if (isset($xml->factory[0]['events'])) {
  223.                 $events = (string)$xml->factory[0]['events'];
  224.                 $this->_eventList preg_split("/[\s,]+/"$events);
  225.             }
  226.  
  227.             if (isset($xml->factory[0]->method)){
  228.                 $methods array();
  229.                 foreach($xml->factory[0]->method as $method){
  230.                     $m new jDaoMethod ($method$this);
  231.                     if (isset ($methods[$m->name])){
  232.                         throw new jDaoXmlException ($this->selector'method.duplicate',$m->name);
  233.                     }
  234.                     $methods[$m->name$m;
  235.                 }
  236.                 $this->_methods array_merge($this->_methods$methods);
  237.             }
  238.         }
  239.     }
  240.  
  241.     /**
  242.     * parse a join definition
  243.     */
  244.     private function _parseTable ($typetable$tabletag){
  245.         $infos $this->getAttr($tabletagarray('name','realname','primarykey','onforeignkey'));
  246.  
  247.         if ($infos['name'=== null )
  248.             throw new jDaoXmlException ($this->selector'table.name');
  249.  
  250.         if($infos['realname'=== null)
  251.             $infos['realname'$infos['name'];
  252.  
  253.         if($infos['primarykey'=== null)
  254.             throw new jDaoXmlException ($this->selector'primarykey.missing');
  255.  
  256.         $infos['pk']preg_split("/[\s,]+/"$infos['primarykey']);
  257.         unset($infos['primarykey']);
  258.  
  259.         if(count($infos['pk']== || $infos['pk'][0== '')
  260.             throw new jDaoXmlException ($this->selector'primarykey.missing');
  261.  
  262.         if($typetable)// for the foreigntable and optionalforeigntable
  263.             if($infos['onforeignkey'=== null)
  264.                 throw new jDaoXmlException ($this->selector'foreignkey.missing');
  265.             $infos['fk']=preg_split("/[\s,]+/",$infos['onforeignkey']);
  266.             unset($infos['onforeignkey']);
  267.             if(count($infos['fk']== || $infos['fk'][0== '')
  268.                 throw new jDaoXmlException ($this->selector'foreignkey.missing');
  269.             if(count($infos['fk']!= count($infos['pk']))
  270.                 throw new jDaoXmlException ($this->selector'foreignkey.missing');
  271.             if($typetable == 1){
  272.                 $this->_ijoins[]=$infos['name'];
  273.             }else{
  274.                 $this->_ojoins[]=array($infos['name'],0);
  275.             }
  276.         }else{
  277.             unset($infos['onforeignkey']);
  278.         }
  279.  
  280.         $infos['fields'array ();
  281.         $this->_tables[$infos['name']] $infos;
  282.  
  283.         return $infos;
  284.     }
  285.  
  286.     /**
  287.     * Try to read all given attributes
  288.     * @param SimpleXmlElement $tag 
  289.     * @param array $requiredattr attributes list
  290.     * @return array attributes and their values
  291.     */
  292.     public function getAttr($tag$requiredattr){
  293.         $res=array();
  294.         foreach($requiredattr as $attr){
  295.             if(isset($tag[$attr]&& trim((string)$tag[$attr]!= '')
  296.                 $res[$attr]=(string)$tag[$attr];
  297.             else
  298.                 $res[$attr]=null;
  299.         }
  300.         return $res;
  301.     }
  302.  
  303.     /**
  304.     * just a quick way to retrieve boolean values from a string.
  305.     *  will accept yes, true, 1 as "true" values
  306.     *  all other values will be considered as false.
  307.     * @return boolean true / false
  308.     */
  309.     public function getBool ($value{
  310.         return in_array (trim ($value)array ('true''1''yes'));
  311.     }
  312.  
  313.     /**
  314.     * the properties list.
  315.     * keys = field code name
  316.     * values = jDaoProperty
  317.     * @return array 
  318.     */
  319.     public function getProperties (return $this->_properties}
  320.  
  321.     /**
  322.     * all tables with their properties, and their own fields
  323.     * keys = table code name
  324.     * values = array()
  325.     *          'name'=> table code name, 'realname'=>'real table name',
  326.     *           'pk'=> primary keys list
  327.     *          'fk'=> foreign keys list
  328.     *          'fields'=>array(list of field code name)
  329.     * @return array 
  330.     */
  331.     public function getTables(){  return $this->_tables;}
  332.  
  333.     /**
  334.     * @return string the primary table code name
  335.     */
  336.     public function getPrimaryTable(){  return $this->_primaryTable;}
  337.  
  338.     /**
  339.      * @return jDaoMethod[] list of jDaoMethod objects
  340.      */
  341.     public function getMethods(){  return $this->_methods;}
  342.  
  343.     /**
  344.     * list of code name of foreign table with a outer join
  345.     * @var array  list of array(table code name, 0)
  346.     */
  347.     public function getOuterJoins(){  return $this->_ojoins;}
  348.  
  349.     /**
  350.     * list of code name of foreign tables with a inner join
  351.     * @return array  the list
  352.     */
  353.     public function getInnerJoins(){  return $this->_ijoins;}
  354.  
  355.     public function getEvents()return $this->_eventList;}
  356.     public function hasEvent($event)return in_array($event,$this->_eventList);}
  357.  
  358.     /**
  359.      * selector of the user record class
  360.      * @return jSelectorDaoRecord 
  361.      */
  362.     public function getUserRecord(return $this->_userRecord;}
  363.  
  364.     /**
  365.      * selector of the imported dao. If can return several selector, if
  366.      * an imported dao import itself an other dao etc.
  367.      * @return jSelectorDao[] 
  368.      */
  369.     public function getImportedDao()return $this->_importedDao;}
  370. }

Documentation generated on Wed, 04 Jan 2017 22:53:23 +0100 by phpDocumentor 1.4.3