Seditio Source
Root |
./othercms/elxis_5.3_atlas_rev2452/components/com_extmanager/includes/extension.xml.php
<?php
/**
* @version        $Id: extension.xml.php 1495 2014-04-29 19:29:20Z sannosi $
* @package        Elxis
* @subpackage    Extensions Manager / XML parser
* @copyright    Copyright (c) 2006-2014 Elxis CMS (http://www.elxis.org). All rights reserved.
* @license        Elxis Public License ( http://www.elxis.org/elxis-public-license.html )
* @author        Elxis Team ( http://www.elxis.org )
* @description     Elxis CMS is free software. Read the license for copyright notices and details
*/

defined('_ELXIS_') or die ('Direct access to this location is not allowed');


class
extensionXML {

    private
$xmlfile = null;
    private
$head = null;
    private
$dependencies = array();
    private
$tabs = array();
    private
$tabsonsave = '';
    private
$errormsg = '';


   
/***************/
    /* CONSTRUCTOR */
    /***************/
   
public function __construct() {
    }


   
/********************/
    /* RESET EVERYTHING */
    /********************/
   
private function reset() {
       
$this->xmlfile = null;
       
$this->head = new stdClass;
       
$this->dependencies = array();
       
$this->tabs = array();
       
$this->tabsonsave = '';
       
$this->errormsg = '';
    }


   
/*****************************/
    /* READ EXTENSION'S XML FILE */
    /*****************************/
   
public function parse($xmlfile, $dependencies=false) {
       
$this->reset();

       
$xmlfile = trim($xmlfile);
        if ((
$xmlfile == '') || !file_exists($xmlfile) || !is_file($xmlfile)) {
           
$this->errormsg = 'XML file not found!';
            return
false;
        }

       
$extension = strtolower(substr(strrchr($xmlfile, '.'), 1));
        if (
$extension != 'xml') {
           
$this->errormsg = 'Given file is not an XML file!';
            return
false;
        }

       
libxml_use_internal_errors(true);
       
$xmlDoc = simplexml_load_file($xmlfile, 'SimpleXMLElement');
        if (!
$xmlDoc) {
            foreach (
libxml_get_errors() as $error) {
               
$this->errormsg = 'Could not parse XML file. Error: '.$error->message.'. Line: '.$error->line;
                break;
            }
            return
false;
        }

        if (
$xmlDoc->getName() != 'package') {
           
$this->errormsg = 'The XML file is not a valid Elxis extension XML!';
            return
false;
        }

       
$type = '';
       
$section = 'frontend';
       
$attrs = $xmlDoc->attributes();
        if (
$attrs) {
            if (isset(
$attrs['type'])) { $type = (string)$attrs['type']; }
            if (isset(
$attrs['section'])) { $section = (string)$attrs['section']; }
        }
        if ((
$type == '') || !in_array($type, array('component', 'module', 'template', 'engine', 'auth', 'plugin'))) {
           
$this->errormsg = 'The type attribute in the XML file is either missing or incorrect!';
            return
false;
        }
        if (
$section != 'backend') { $section = 'frontend'; }

       
$this->head->type = $type;
       
$this->head->section = $section;

       
$req_elements = array('name', 'title', 'created', 'author', 'version');
        foreach (
$req_elements as $req_element) {
            if (!isset(
$xmlDoc->$req_element)) {
               
$this->errormsg = ucfirst($req_element).' node was not found in the XML file!';
                return
false;
            }

           
$v = (string)$xmlDoc->$req_element;
           
$v = trim($v);
            if (
$v == '') {
               
$this->errormsg = ucfirst($req_element).' node can not be empty in the XML file!';
                return
false;
            }

            if (
$req_element == 'name') {
                switch (
$this->head->type) {
                    case
'component': $prf = 'com_'; break;
                    case
'module': $prf = 'mod_'; break;
                    case
'template': case 'engine': case 'auth': case 'plugin': default: $prf = ''; break;
                }

                if ((
$prf != '') && (strpos($v, $prf) !== 0)) {
                   
$this->errormsg = 'A '.ucfirst($this->head->type).' name should start with '.$prf.'!';
                    return
false;
                }
            } else if (
$req_element == 'created') {
                if (
strlen($v) == 10) { $v = $v .= ' 00:00:00'; }
                if (
strlen($v) != 19) { $v = gmdate('Y-m-d H:i:s'); }
            } else if (
$req_element == 'version') {
                if (!
is_numeric($v)) {
                   
$this->errormsg = ucfirst($req_element).' node in the XML file should have a numeric value!';
                    return
false;
                }

                if (
$v <= 0) {
                   
$this->errormsg = ucfirst($req_element).' node in the XML file should have a positive float value!';
                    return
false;
                }
            }

           
$this->head->$req_element = $v;
        }

       
$other_elements = array('authoremail', 'authorurl',  'link', 'copyright', 'license', 'licenseurl', 'description');
        foreach (
$other_elements as $other_element) {
            if (!isset(
$xmlDoc->$other_element)) {
               
$this->head->$other_element = null;
                continue;
            }

           
$v = (string)$xmlDoc->$other_element;
           
$v = trim($v);
           
$this->head->$other_element = $v;
        }

        if (
$dependencies) {
           
$this->dependencies = $this->parseDependencies($xmlDoc);
        }

        if (isset(
$xmlDoc->tabs)) {
           
$i = 1;
           
$xmldir = dirname($xmlfile).'/';
           
$eLang = eFactory::getLang();
           
           
$onsave = '';
           
$attrs = $xmlDoc->tabs->attributes();
            if (
$attrs) {
                if (isset(
$attrs['onsave'])) { $onsave = (string)$attrs['onsave']; }
                if (
trim($onsave) != '') {
                    if (!
file_exists($xmldir.$onsave) || !is_file($xmldir.$onsave)) {
                       
$onsave = '';
                    } else {
                       
$onsave = $onsave;//relative path
                   
}
                }
            }

            foreach (
$xmlDoc->tabs as $tabs) {
                if (!isset(
$tabs->tab)) { continue; }
                foreach (
$tabs->children() as $tab) {
                   
$attrs = $tab->attributes();

                   
$label = '';
                   
$include = '';
                   
$contents = '';
                    if (
$attrs) {
                        if (isset(
$attrs['label'])) { $label = (string)$attrs['label']; }
                        if (isset(
$attrs['include'])) { $include = (string)$attrs['include']; $include = ltrim($include, '/'); }
                    }

                    if (
trim($label) == '') {
                       
$label = 'Tab '.$i;
                    } else {
                       
$label = $eLang->silentGet($label);
                    }
                    if (
trim($include) != '') {
                        if (!
file_exists($xmldir.$include) || !is_file($xmldir.$include)) {
                           
$include = '';
                        } else {
                           
$include = $xmldir.$include;//absolute path
                       
}
                    } else {
                       
$contents = (string)$tab;
                    }

                    if ((
$include != '') || ($contents != '')) {
                       
$this->tabs[] = array('label' => $label, 'include' => $include, 'contents' => $contents);
                    }
                }
            }
            if (
$this->tabs) { $this->tabsonsave = $onsave; }
        }

        return
true;
    }


   
/**********************************/
    /* PARSE EXTENSION'S DEPENDENCIES */
    /**********************************/
   
private function parseDependencies($xmlDoc) {
       
$dependencies = array();
        if (!isset(
$xmlDoc->dependencies)) { return $dependencies; }
        if (!
$xmlDoc->dependencies->children()) { return $dependencies; }
        foreach (
$xmlDoc->dependencies->children() as $dependency) {
           
$extension = (string)$dependency;
           
$extension = trim(strtolower($extension));
            if (
$extension == '') { continue; }
           
$attrs = $dependency->attributes();
            if (!isset(
$attrs['type'])) { continue; }
            if (!isset(
$attrs['version'])) { continue; }
           
$type = (string)$attrs['type'];
           
$version = (string)$attrs['version'];
            if (
$version == '') { continue; }

           
$versions = explode(',', $version);

            switch (
$type) {
                case
'component':
                   
$extension = preg_replace('/^(com\_)/', '', $extension);
                break;
                case
'module':
                   
$extension = preg_replace('/^(mod\_)/', '', $extension);
                break;
                default: break;
            }

           
$dpc = new stdClass;
           
$dpc->type = strtolower($type);
           
$dpc->versions = $versions;
           
$dpc->extension = $extension;
           
$dpc->installed = false;
           
$dpc->iversion = 0;
           
$dpc->icompatible = false;
           
$dependencies[] = $dpc;
            unset(
$dpc);
        }
        return
$dependencies;
    }


   
/********************************************/
    /* CHECK DEPENDENCIES EXISTANCE AND VERSION */
    /********************************************/
   
public function checkDependencies() {
        if (!
$this->dependencies) { return; }
        foreach (
$this->dependencies as $k => $dpc) {
            if (
$dpc->type == 'core') {
               
$this->dependencies[$k]->installed = true;
                if (
$dpc->extension == 'elxis') {
                   
$this->dependencies[$k]->iversion = eFactory::getElxis()->getVersion();
                   
$this->dependencies[$k]->icompatible = $this->isCompatible($this->dependencies[$k]->iversion, $dpc->versions);
                }
            } else if (
in_array($dpc->type, array('component', 'module', 'template', 'atemplate', 'engine', 'auth', 'plugin'))) {
               
$info = $this->quickXML($dpc->type, $dpc->extension);
               
$this->dependencies[$k]->installed = $info['installed'];
               
$this->dependencies[$k]->iversion = $info['version'];
               
$this->dependencies[$k]->icompatible = $this->isCompatible($this->dependencies[$k]->iversion, $dpc->versions);
            }
        }
    }


   
/***********************************************************************/
    /* GET QUICKLY AN EXTENSION'S VERSION AND SOME MORE INFO FROM XML FILE */
    /***********************************************************************/
   
public function quickXML($type, $name) {
       
$info = array('installed' => false, 'version' => 0, 'title' => '', 'created' => '', 'author'=> '', 'authorurl' => '', 'section' => 'frontend');
       
$xmlfile = '';
        if (
$type == 'component') {
           
$name = preg_replace('/^(com\_)/', '', $name);
            if (
file_exists(ELXIS_PATH.'/components/com_'.$name.'/'.$name.'.xml')) {
               
$xmlfile = ELXIS_PATH.'/components/com_'.$name.'/'.$name.'.xml';
               
$info['installed'] = true;
            }
        } else if (
$type == 'module') {
           
$name = preg_replace('/^(mod\_)/', '', $name);
            if (
file_exists(ELXIS_PATH.'/modules/mod_'.$name.'/mod_'.$name.'.xml')) {
               
$xmlfile = ELXIS_PATH.'/modules/mod_'.$name.'/mod_'.$name.'.xml';
               
$info['installed'] = true;
            } else if (
file_exists(ELXIS_PATH.'/modules/mod_'.$name.'/'.$name.'.xml')) {
               
$xmlfile = ELXIS_PATH.'/modules/mod_'.$name.'/'.$name.'.xml';
               
$info['installed'] = true;
            }
        } else if (
$type == 'atemplate') {
            if (
file_exists(ELXIS_PATH.'/templates/admin/'.$name.'/'.$name.'.xml')) {
               
$xmlfile = ELXIS_PATH.'/templates/admin/'.$name.'/'.$name.'.xml';
               
$info['installed'] = true;
            }
        } else if (
$type == 'template') {
            if (
file_exists(ELXIS_PATH.'/templates/'.$name.'/'.$name.'.xml')) {
               
$xmlfile = ELXIS_PATH.'/templates/'.$name.'/'.$name.'.xml';
               
$info['installed'] = true;
            } else if (
file_exists(ELXIS_PATH.'/templates/admin/'.$name.'/'.$name.'.xml')) {
               
$xmlfile = ELXIS_PATH.'/templates/admin/'.$name.'/'.$name.'.xml';
               
$info['installed'] = true;
            }
        } else if (
$type == 'engine') {
            if (
file_exists(ELXIS_PATH.'/components/com_search/engines/'.$name.'/'.$name.'.engine.xml')) {
               
$xmlfile = ELXIS_PATH.'/components/com_search/engines/'.$name.'/'.$name.'.engine.xml';
               
$info['installed'] = true;
            }
        } else if (
$type == 'auth') {
            if (
file_exists(ELXIS_PATH.'/components/com_user/auth/'.$name.'/'.$name.'.auth.xml')) {
               
$xmlfile = ELXIS_PATH.'/components/com_user/auth/'.$name.'/'.$name.'.auth.xml';
               
$info['installed'] = true;
            }
        } else if (
$type == 'plugin') {
            if (
file_exists(ELXIS_PATH.'/components/com_content/plugins/'.$name.'/'.$name.'.plugin.xml')) {
               
$xmlfile = ELXIS_PATH.'/components/com_content/plugins/'.$name.'/'.$name.'.plugin.xml';
               
$info['installed'] = true;
            }
        }

        if (
$xmlfile == '') { return $info; }
       
libxml_use_internal_errors(true);
       
$xmlDoc = simplexml_load_file($xmlfile, 'SimpleXMLElement');
        if (!
$xmlDoc) { return $info; }
        if (
$xmlDoc->getName() != 'package') { return $info; }
       
$attrs = $xmlDoc->attributes();
        if (
$attrs) {
            if (isset(
$attrs['section'])) { $info['section'] = (string)$attrs['section']; }
        }
        if (!isset(
$xmlDoc->version)) { return $info; }
       
$v = (string)$xmlDoc->version;
       
$info['version'] = trim($v);
        if (isset(
$xmlDoc->title)) { $info['title'] = (string)$xmlDoc->title; }
        if (isset(
$xmlDoc->created)) { $info['created'] = (string)$xmlDoc->created; }
        if (isset(
$xmlDoc->author)) { $info['author'] = (string)$xmlDoc->author; }
        if (isset(
$xmlDoc->authorurl)) { $info['authorurl'] = (string)$xmlDoc->authorurl; }
        unset(
$xmlDoc);
        return
$info;
    }


   
/*********************************************************************/
    /* CHECK VERSION COMPATIBILITY (format: 4.x or 4.x.y where x,y: 0-9) */
    /*********************************************************************/
   
public function isCompatible($iversion, $versions) {
        foreach (
$versions as $version) {
            if (
$iversion == $version) {
                return
true;
            } else if (
preg_match('/(x)$/', $version)) {
               
$av = array();
                for (
$i=0; $i<10; $i++) {
                   
$av[] = str_replace('x', $i, $version);
                }
                if (
in_array($iversion, $av)) { return true; }
            } else if (
preg_match('/(\+)$/', $version)) {
               
$v = str_replace('+', '', $version);
               
$parts = explode('.', $v);
               
$last = count($parts) - 1;
                if (
$last == 0) {
                    if (
version_compare($iversion, $v, '>=') === true) {
                        return
true;
                    } else {
                        break;
                    }
                }

               
$first = '';
                foreach (
$parts as $k => $part) {
                    if (
$k == $last) { break; }
                   
$first .= $part.'.';
                }

               
$av = array();
               
$num = (int)$parts[$last];
                for (
$i=$num; $i<10; $i++) { $av[] = $first.$i; }
                if (
in_array($iversion, $av)) { return true; }
            } else {
               
//do nothing
           
}
        }
        return
false;
    }


   
/*****************/
    /* GET HEAD DATA */
    /*****************/
   
public function getHead() {
        return
$this->head;
    }


   
/********************/
    /* GET DEPENDENCIES */
    /********************/
   
public function getDependencies() {
        return
$this->dependencies;
    }


   
/*********************/
    /* GET ERROR MESSAGE */
    /*********************/
   
public function getErrorMsg() {
        return
$this->errormsg;
    }


   
/*****************/
    /* GET TABS DATA */
    /*****************/
   
public function getTabs() {
        return
$this->tabs;
    }


   
/***************************/
    /* GET TABS ON SAVE ACTION */
    /***************************/
   
public function getTabsOnSave() {
        return
$this->tabsonsave;
    }

}

?>