Location: PHPKode > projects > Template CMS > templatecms_2_0_3_en/template_cms/engine/XML.php
<?php  if (!defined('TEMPLATE_CMS_ACCESS')) exit('No direct script access allowed');

    /**
     *	XMLDB API module. Use SimpleXML and xPath to navigate through elements and attributes in an XML document. See http://www.w3schools.com/xpath/
     *	@package TemplateCMS
     *  @subpackage Engine
     *	@author Romanenko Sergey / Awilum
     *	@copyright 2011 Romanenko Sergey / Awilum
     *	@version $Id$
     *	@since 2.0
     *  @license http://opensource.org/licenses/gpl-license.php GNU Public License
     *  TemplateCMS is free software. This version may have been modified pursuant
     *  to the GNU General Public License, and as distributed it includes or
     *  is derivative of works licensed under the GNU General Public License or
     *  other free or open source software licenses.
     *  See COPYING.txt for copyright notices and details.
     *  @filesource
     */



    /**
     * Create safe xml data. Removes dangerous characters for xml database.
     * @param string $str String
     */     
    function safeXMLdata($str) {
        return xssClean($str);
    } 

    /**
     * Get XML file
     * @param string $file File name
     * @return array
     */
    function getXML($file,$force=false) {
        // For CMS API XML file force method
        if($force) {
            $xml = file_get_contents($file);
            $data = simplexml_load_string($xml);
            return $data;
        } else {
            if(fileExists($file)) {
                $xml = file_get_contents($file);
                $data = simplexml_load_string($xml);
                return $data;
            } else {
                return false;
            }
        }
    }
    
    /**
     * Create new XML database
     * @param string $file XML database file
     */
    function createXMLdb($file) {
        createFile($file.'.xml','<?xml version="1.0" encoding="UTF-8"?><root><options><option_autoincrement>0</option_autoincrement></options></root>');
    }

    /**
     * Delete XML database file
     * @param string $file Path to xml database file
     */
    function dropXMLdb($file) {
        deleteFile($file);
    }

    /**
     * Get XML data base. Simple load XML file and return its name and XML object
     * @param array $file XML file
     * @return mixed
     */
    function getXMLdb($file) {
        if(fileExists($file)) {
            $data = array('xml_object'   => getXML($file),
                          'xml_filename' => $file);
            return $data;
        } else {
            return false;
        }
    }

    /**
     * Format XML and save
     * @param array $xml_db Array of database name and XML object
     */
    function saveXML($xml_db) {
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;

        // Save new xml data to xml file only if loadXML successful.        
        // Preventing the destruction of the database unsafe data.
        // note: If loadXML !successful then saveXML() add&save empty record.
        //       This record cant be removed by deleteXMLRecord[Where]() Problem solved by hand removing...
        //       Possible solution is modify deleteXMLRecord[Where]() or prevent add&saving of such records.
        // the result now: database is not destroyed :)
        if($dom->loadXML($xml_db['xml_object']->asXML())) {              
            $dom->save($xml_db['xml_filename']);                  
        } else {            
            // report about errors...
        }                

    }

    /**
     * Add new record to xml file
     * Example:
     *   insertXMLRecord($xml_db,'my_record_name',array('field1_name'=>'field1_value',
     *                                                  'field2_name'=>'field1_value'));
     * @param array $xml_db Array database name and XML object
     * @param string $record_name Name of new record
     * @param array $fields Record fields to insert
     * @param array $record_attr Attributes of new record
     */
    function insertXMLRecord($xml_db, $record_name, $fields=array(), $record_attr=array()) {
        // Find autoincrement option
        $inc = selectXMLRecord($xml_db,"options/option_autoincrement");
            
        // Add record
        $node = $xml_db['xml_object']->addChild(safeXMLdata($record_name));

        // Add attribute for new record: unique ID
        $node->addAttribute('id',$inc+1);

        // Update autoincrement
        updateXMLRecordWhere($xml_db,"options",array('option_autoincrement'=>$inc+1));

        // If some else record attributes exists add them
        if(count($record_attr) !== 0) {
            foreach($record_attr as $key=>$value) {
                $node->addAttribute($key,safeXMLdata($value));
            }
        }

        // If exists fields to insert then insert them
        if(count($fields) !== 0) {
            foreach($fields as $key=>$value) {                
                $node->addChild($key,safeXMLdata($value));
            }
        }

        // Save xml file
        saveXML($xml_db);
    }

    /**
     * Select record(s) in xml file
     * Example:
     *   selectXMLRecord($xml_db,"//menu");       // Select one record
     *   selectXMLRecord($xml_db,"//menu",'all'); // Select all records
     *   selectXMLRecord($xml_db,"//menu",2);     // Select 2 records
     *   selectXMLRecord($xml_db,"//menu",2,2);   // Select 2 records after record id 2
     * @param array $xml_db Array database name and XML object
     * @param string $query XPath query
     * @param integer $row_count Row count. To select all records write 'all'
     * @param integer $offset Offset
     * @return object
     */
    function selectXMLRecord($xml_db, $query, $row_count=null, $offset=null) {
        $tmp = $xml_db['xml_object']->xpath($query);

        $data = array();
        
        if($row_count == null) {
            return isset($tmp[0])? $tmp[0]: null;
        } else {
            if($row_count == 'all') {
                foreach($tmp as $record) {
                    $data[] = $record;
                }                
                return $data;
            } else {
                foreach($tmp as $record) {
                    $data[] = $record;
                }
                // If offset is null slice array from end else from begin
                if($offset == null) {
                    return array_slice($data, -$row_count, $row_count);
                } else {
                    return array_slice($data, $offset, $row_count);
                }
            }
        }

    }

    /**
     * Select fields in xml records. Records get by selectXMLRecord() function.
     * Example:
     *   selectXMLFields($xml_db,array('id','name','date'), 'date', 'DESC'));
     * @param object $records Records
     * @param array $fields Array of fields to select
     * @param string $order_by Order by field
     * @param sring $order Order type ASC or DESC. Default is ASC
     * @return array
     */
    function selectXMLfields($records, $fields, $order_by, $order = 'ASC') {
        $count = 0;
        if(count($records) > 0) {
            foreach($records as $key=>$record) {
                foreach($fields as $field) {
                    $record_array[$count][$field] = $record->$field;
                }
                $record_array[$count]['id'] = $record['id'];
                $record_array[$count]['sort'] = $record->$order_by;
                $count++;
            }
            $s = subval_sort($record_array, 'sort', $order);
            return $s;
        }
    }
  
    /**
     * Delete current record in xml file
     * Example:
     *   deleteXMLRecord($xml_db,'my_record_name',1);
     * @param array $xml_db Array database name and XML object
     * @param string $record_name Name of new record
     * @param integer $id Record ID
     */
    function deleteXMLRecord($xml_db, $record_name, $id) {
        // xPath query
        $query = "//".$record_name."[@id='".$id."']";

        // Find record to delete
        $xml_arr = selectXMLRecord($xml_db,$query);

        // If its exists then delete it
        if(count($xml_arr) !== 0) {
            unset($xml_arr[0]);
        }

        // Save xml file
        saveXML($xml_db);
    }

    /**
     * Delete with xPath query record in xml file
     * @param array $xml_db Array database name and XML object
     * @param string $query xPath query
     */
    function deleteXMLRecordWhere($xml_db, $query) {
        // Find record to delete
        $xml_arr = selectXMLRecord($xml_db,$query);
        
        // If its exists then delete it
        if(count($xml_arr) !== 0) {
            unset($xml_arr[0]);
        }

        // Save xml file
        saveXML($xml_db);
    }

    /**
     * Update record with xPath query in XML file
     * Example:
     *   updateXMLRecordWhere($xml_db,"//name[@id='1']",array('field1_name'=>'new_field1_value',
     *                                                        'field2_name'=>'new_field1_value'));
     * @param array $xml_db Array database name and XML object
     * @param string $query XPath query
     * @param array $fields Record fields to udpate
     */
    function updateXMLRecordWhere($xml_db, $query, $fields=array()) {
        // Find record to delete
        $xml_arr = selectXMLRecord($xml_db,$query);

        // If its exists then delete it
        if(count($fields) !== 0) {
            foreach($fields as $key=>$value) {
                $xml_arr->$key = safeXMLdata($value);
            }
        }

        // Save xml file
        saveXML($xml_db);
    }

    /**
     * Update current record in XML file
     * Example:
     *   updateXMLRecord($xml_db,'my_record_name',1,array('field1_name'=>'new_field1_value',
     *                                                    'field2_name'=>'new_field1_value'));
     * @param array $xml_db Array database name and XML object
     * @param string $record_name Record name to update
     * @param integer $id Record ID
     * @param array $fields Record fields to udpate
     */
    function updateXMLRecord($xml_db, $record_name, $id, $fields=array()) {
        // xPath query
        $query = "//".$record_name."[@id='".(int)$id."']";

        // Find record to delete
        $xml_arr = selectXMLRecord($xml_db,$query);
				
        // If its exists then update it
        if(count($fields) !== 0) {
            foreach($fields as $key=>$value) {
                // Clear record fileds
                unset($xml_arr->$key);
                $xml_arr->addChild($key,safeXMLdata($value));
            }
        }

        // Save xml file
        saveXML($xml_db);
    }

    /**
     * Get last record id
     * @param array $xml_db Array database name and XML object
     * @param string $record_name Record name
     * @return object
     */
    function lastXMLRecordId($xml_db, $record_name) {
        $query = "//".$record_name."[last()]";
        $data = $xml_db['xml_object']->xpath($query);
        return $data[0]['id'];
    }

    /**
     * Get count of records
     * @param array $xml_db Array database name and XML object
     */
    function countXMLRecords($xml_db) {
        return count($xml_db['xml_object'])-1;
    }
Return current item: Template CMS