Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/backup/util/structure/backup_nested_element.class.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00030 class backup_nested_element extends base_nested_element implements processable {
00031 
00032     protected $var_array; // To be used in case we pass one in-memory structure
00033     protected $table;     // Table (without prefix) to fetch records from
00034     protected $sql;       // Raw SQL to fetch records from
00035     protected $params;    // Unprocessed params as specified in the set_source() call
00036     protected $procparams;// Processed (path resolved) params array
00037     protected $aliases;   // Define DB->final element aliases
00038     protected $fileannotations;   // array of file areas to be searched by file annotations
00039     protected $counter;   // Number of instances of this element that have been processed
00040 
00048     public function __construct($name, $attributes = null, $final_elements = null) {
00049         parent::__construct($name, $attributes, $final_elements);
00050         $this->var_array = null;
00051         $this->table     = null;
00052         $this->sql       = null;
00053         $this->params    = null;
00054         $this->procparams= null;
00055         $this->aliases   = array();
00056         $this->fileannotations = array();
00057         $this->counter   = 0;
00058     }
00059 
00060     public function process($processor) {
00061         if (!$processor instanceof base_processor) { // No correct processor, throw exception
00062             throw new base_element_struct_exception('incorrect_processor');
00063         }
00064 
00065         $iterator = $this->get_iterator($processor); // Get the iterator over backup-able data
00066 
00067         foreach ($iterator as $key => $values) { // Process each "ocurrrence" of the nested element (recordset or array)
00068 
00069             // Fill the values of the attributes and final elements with the $values from the iterator
00070             $this->fill_values($values);
00071 
00072             // Perform pre-process tasks for the nested_element
00073             $processor->pre_process_nested_element($this);
00074 
00075             // Delegate the process of each attribute
00076             foreach ($this->get_attributes() as $attribute) {
00077                 $attribute->process($processor);
00078             }
00079 
00080             // Main process tasks for the nested element, once its attributes have been processed
00081             $processor->process_nested_element($this);
00082 
00083             // Delegate the process of each final_element
00084             foreach ($this->get_final_elements() as $final_element) {
00085                 $final_element->process($processor);
00086             }
00087 
00088             // Delegate the process to the optigroup
00089             if ($this->get_optigroup()) {
00090                 $this->get_optigroup()->process($processor);
00091             }
00092 
00093             // Delegate the process to each child nested_element
00094             foreach ($this->get_children() as $child) {
00095                 $child->process($processor);
00096             }
00097 
00098             // Perform post-process tasks for the nested element
00099             $processor->post_process_nested_element($this);
00100 
00101             // Everything processed, clean values before next iteration
00102             $this->clean_values();
00103 
00104             // Increment counter for this element
00105             $this->counter++;
00106 
00107             // For root element, check we only have 1 element
00108             if ($this->get_parent() === null && $this->counter > 1) {
00109                 throw new base_element_struct_exception('root_only_one_ocurrence', $this->get_name());
00110             }
00111         }
00112         // Close the iterator (DB recordset / array iterator)
00113         $iterator->close();
00114     }
00115 
00116     public function set_source_array($arr) {
00117         // TODO: Only elements having final elements can set source
00118         $this->var_array = $arr;
00119     }
00120 
00121     public function set_source_table($table, $params) {
00122         if (!is_array($params)) { // Check we are passing array
00123             throw new base_element_struct_exception('setsourcerequiresarrayofparams');
00124         }
00125         // TODO: Only elements having final elements can set source
00126         $this->table = $table;
00127         $this->procparams = $this->convert_table_params($params);
00128     }
00129 
00130     public function set_source_sql($sql, $params) {
00131         if (!is_array($params)) { // Check we are passing array
00132             throw new base_element_struct_exception('setsourcerequiresarrayofparams');
00133         }
00134         // TODO: Only elements having final elements can set source
00135         $this->sql = $sql;
00136         $this->procparams = $this->convert_sql_params($params);
00137     }
00138 
00139     public function set_source_alias($dbname, $finalelementname) {
00140         // Get final element
00141         $finalelement = $this->get_final_element($finalelementname);
00142         if (!$finalelement) { // Final element incorrect, throw exception
00143             throw new base_element_struct_exception('incorrectaliasfinalnamenotfound', $finalelementname);
00144         } else {
00145             $this->aliases[$dbname] = $finalelement;
00146         }
00147     }
00148 
00149     public function annotate_files($component, $filearea, $elementname, $filesctxid = null) {
00150         if (!array_key_exists($component, $this->fileannotations)) {
00151             $this->fileannotations[$component] = array();
00152         }
00153 
00154         if ($elementname !== null) { // Check elementname is valid
00155             $elementname = $this->find_element($elementname); //TODO: no warning here? (skodak)
00156         }
00157 
00158         if (array_key_exists($filearea, $this->fileannotations[$component])) {
00159             throw new base_element_struct_exception('annotate_files_duplicate_annotation', "$component/$filearea/$elementname");
00160         }
00161 
00162         $info = new stdclass();
00163         $info->element   = $elementname;
00164         $info->contextid = $filesctxid;
00165         $this->fileannotations[$component][$filearea] = $info;
00166     }
00167 
00168     public function annotate_ids($itemname, $elementname) {
00169         $element = $this->find_element($elementname);
00170         $element->set_annotation_item($itemname);
00171     }
00172 
00177     public function get_file_annotations() {
00178         return $this->fileannotations;
00179     }
00180 
00181     public function get_source_array() {
00182         return $this->var_array;
00183     }
00184 
00185     public function get_source_table() {
00186         return $this->table;
00187     }
00188 
00189     public function get_source_sql() {
00190         return $this->sql;
00191     }
00192 
00193     public function get_counter() {
00194         return $this->counter;
00195     }
00196 
00202     public function fill_values($values) {
00203         $values = (array)$values;
00204 
00205         foreach ($values as $key => $value) {
00206             $found = 0;
00207             if ($attribute = $this->get_attribute($key)) { // Set value for attributes
00208                 $attribute->set_value($value);
00209                 $found++;
00210             }
00211             if ($final = $this->get_final_element($key)) { // Set value for final elements
00212                 $final->set_value($value);
00213                 $found++;
00214             }
00215             if (isset($this->aliases[$key])) { // Last chance, set value by processing final element aliases
00216                 $this->aliases[$key]->set_value($value);
00217                 $found++;
00218             }
00219             // Found more than once, notice
00220                 // TODO: Route this through backup loggers
00221             if ($found > 1) {
00222                 debugging('Key found more than once ' . $key, DEBUG_DEVELOPER);
00223             }
00224         }
00225 
00226     }
00227 
00228 // Protected API starts here
00229 
00230     protected function convert_table_params($params) {
00231         return $this->convert_sql_params($params);
00232     }
00233 
00234     protected function convert_sql_params($params) {
00235         $procparams = array(); // Reset processed params
00236         foreach ($params as $key => $param) {
00237             $procparams[$key] = $this->find_element($param);
00238         }
00239         return $procparams;
00240     }
00241 
00242     protected function find_element($param) {
00243         if ($param == backup::VAR_PARENTID) { // Look for first parent having id attribute/final_element
00244             $param = $this->find_first_parent_by_name('id');
00245 
00246         // If the param is array, with key 'sqlparam', return the value without modifications
00247         } else if (is_array($param) && array_key_exists('sqlparam', $param)) {
00248             return $param['sqlparam'];
00249 
00250         } else if (((int)$param) >= 0) {  // Search by path if param isn't a backup::XXX candidate
00251             $param = $this->find_element_by_path($param);
00252         }
00253         return $param; // Return the param unmodified
00254     }
00255 
00260     protected function get_new_attribute($name) {
00261         return new backup_attribute($name);
00262     }
00263 
00268     protected function get_new_final_element($name) {
00269         return new backup_final_element($name);
00270     }
00271 
00276     protected function get_iterator($processor) {
00277         return backup_structure_dbops::get_iterator($this, $this->procparams, $processor);
00278     }
00279 }
 All Data Structures Namespaces Files Functions Variables Enumerations