Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/backup/util/helper/restore_log_rule.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 
00025 defined('MOODLE_INTERNAL') || die();
00026 
00036 class restore_log_rule implements processable {
00037 
00038     protected $module;   // module of the log record
00039     protected $action;   // action of the log record
00040 
00041     protected $urlread;   // url format of the log record in backup file
00042     protected $inforead;  // info format of the log record in backup file
00043 
00044     protected $modulewrite;// module of the log record to be written (defaults to $module if not specified)
00045     protected $actionwrite;// action of the log record to be written (defaults to $action if not specified)
00046 
00047     protected $urlwrite; // url format of the log record to be written (defaults to $urlread if not specified)
00048     protected $infowrite;// info format of the log record to be written (defaults to $inforead if not specified)
00049 
00050     protected $urlreadregexp; // Regexps for extracting information from url and info
00051     protected $inforeadregexp;
00052 
00053     protected $allpairs; // to acummulate all tokens and values pairs on each log record restored
00054 
00055     protected $urltokens; // tokens present int the $urlread attribute
00056     protected $infotokens;// tokens present in the $inforead attribute
00057 
00058     protected $fixedvalues;    // Some values that will have precedence over mappings to save tons of DB mappings
00059 
00060     protected $restoreid;
00061 
00062     public function __construct($module, $action, $urlread, $inforead,
00063                                 $modulewrite = null, $actionwrite = null, $urlwrite = null, $infowrite = null) {
00064         $this->module    = $module;
00065         $this->action    = $action;
00066         $this->urlread   = $urlread;
00067         $this->inforead  = $inforead;
00068         $this->modulewrite = is_null($modulewrite) ? $module : $modulewrite;
00069         $this->actionwrite= is_null($actionwrite) ? $action : $actionwrite;
00070         $this->urlwrite = is_null($urlwrite) ? $urlread : $urlwrite;
00071         $this->infowrite= is_null($infowrite) ? $inforead : $infowrite;
00072         $this->allpairs = array();
00073         $this->urltokens = array();
00074         $this->infotokens= array();
00075         $this->urlreadregexp = null;
00076         $this->inforeadregexp = null;
00077         $this->fixedvalues = array();
00078         $this->restoreid = null;
00079 
00080         // TODO: validate module, action are valid => exception
00081 
00082         // Calculate regexps and tokens, both for urlread and inforead
00083         $this->calculate_url_regexp($this->urlread);
00084         $this->calculate_info_regexp($this->inforead);
00085     }
00086 
00087     public function set_restoreid($restoreid) {
00088         $this->restoreid = $restoreid;
00089     }
00090 
00091     public function set_fixed_values($values) {
00092         //TODO: check $values is array => exception
00093         $this->fixedvalues = $values;
00094     }
00095 
00096     public function get_key_name() {
00097         return $this->module . '-' . $this->action;
00098     }
00099 
00100     public function process($log) {
00101 
00102         // Reset the allpairs array
00103         $this->allpairs = array();
00104 
00105         $urlmatches  = array();
00106         $infomatches = array();
00107         // Apply urlreadregexp to the $log->url if necessary
00108         if ($this->urlreadregexp) {
00109             preg_match($this->urlreadregexp, $log->url, $urlmatches);
00110             if (empty($urlmatches)) {
00111                 return false;
00112             }
00113         } else {
00114             if (!is_null($this->urlread)) { // If not null, use it (null means unmodified)
00115                 $log->url = $this->urlread;
00116             }
00117         }
00118         // Apply inforeadregexp to the $log->info if necessary
00119         if ($this->inforeadregexp) {
00120             preg_match($this->inforeadregexp, $log->info, $infomatches);
00121             if (empty($infomatches)) {
00122                 return false;
00123             }
00124         } else {
00125             if (!is_null($this->inforead)) { // If not null, use it (null means unmodified)
00126                 $log->info = $this->inforead;
00127             }
00128         }
00129 
00130         // If there are $urlmatches, let's process them
00131         if (!empty($urlmatches)) {
00132             array_shift($urlmatches); // Take out first element
00133             if (count($urlmatches) !== count($this->urltokens)) { // Number of matches must be number of tokens
00134                 return false;
00135             }
00136             // Let's process all the tokens and matches, using them to parse the urlwrite
00137             $log->url = $this->parse_tokens_and_matches($this->urltokens, $urlmatches, $this->urlwrite);
00138         }
00139 
00140         // If there are $infomatches, let's process them
00141         if (!empty($infomatches)) {
00142             array_shift($infomatches); // Take out first element
00143             if (count($infomatches) !== count($this->infotokens)) { // Number of matches must be number of tokens
00144                 return false;
00145             }
00146             // Let's process all the tokens and matches, using them to parse the infowrite
00147             $log->info = $this->parse_tokens_and_matches($this->infotokens, $infomatches, $this->infowrite);
00148         }
00149 
00150         // Arrived here, if there is any pending token in $log->url or $log->info, stop
00151         if ($this->extract_tokens($log->url) || $this->extract_tokens($log->info)) {
00152             return false;
00153         }
00154 
00155         // Finally, set module and action
00156         $log->module = $this->modulewrite;
00157         $log->action = $this->actionwrite;
00158 
00159         return $log;
00160     }
00161 
00162 // Protected API starts here
00163 
00164     protected function parse_tokens_and_matches($tokens, $values, $content) {
00165 
00166         $pairs = array_combine($tokens, $values);
00167         ksort($pairs); // First literals, then mappings
00168         foreach ($pairs as $token => $value) {
00169             // If one token has already been processed, continue
00170             if (array_key_exists($token, $this->allpairs)) {
00171                 continue;
00172             }
00173 
00174             // If the pair is one literal token, just keep it unmodified
00175             if (substr($token, 0, 1) == '[') {
00176                 $this->allpairs[$token] = $value;
00177 
00178             // If the pair is one mapping token, let's process it
00179             } else if (substr($token, 0, 1) == '{') {
00180                 $ctoken = $token;
00181 
00182                 // First, resolve mappings to literals if necessary
00183                 if (substr($token, 1, 1) == '[') {
00184                     $literaltoken = trim($token, '{}');
00185                     if (array_key_exists($literaltoken, $this->allpairs)) {
00186                         $ctoken = '{' . $this->allpairs[$literaltoken] . '}';
00187                     }
00188                 }
00189 
00190                 // Look for mapping in fixedvalues before going to DB
00191                 $plaintoken = trim($ctoken, '{}');
00192                 if (array_key_exists($plaintoken, $this->fixedvalues)) {
00193                     $this->allpairs[$token] = $this->fixedvalues[$plaintoken];
00194 
00195                  // Last chance, fetch value from backup_ids_temp, via mapping
00196                 } else {
00197                     if ($mapping = restore_dbops::get_backup_ids_record($this->restoreid, $plaintoken, $value)) {
00198                         $this->allpairs[$token] = $mapping->newitemid;
00199                     }
00200                 }
00201             }
00202         }
00203 
00204         // Apply all the conversions array (allpairs) to content
00205         krsort($this->allpairs); // First mappings, then literals
00206         $content = str_replace(array_keys($this->allpairs), $this->allpairs, $content);
00207 
00208         return $content;
00209     }
00210 
00211     protected function calculate_url_regexp($urlexpression) {
00212         // Detect all the tokens in the expression
00213         if ($tokens = $this->extract_tokens($urlexpression)) {
00214             $this->urltokens = $tokens;
00215             // Now, build the regexp
00216             $this->urlreadregexp = $this->build_regexp($urlexpression, $this->urltokens);
00217         }
00218     }
00219 
00220     protected function calculate_info_regexp($infoexpression) {
00221         // Detect all the tokens in the expression
00222         if ($tokens = $this->extract_tokens($infoexpression)) {
00223             $this->infotokens = $tokens;
00224             // Now, build the regexp
00225             $this->inforeadregexp = $this->build_regexp($infoexpression, $this->infotokens);
00226         }
00227     }
00228 
00229     protected function extract_tokens($expression) {
00230         // Extract all the tokens enclosed in square and curly brackets
00231         preg_match_all('~\[[^\]]+\]|\{[^\}]+\}~', $expression, $matches);
00232         return $matches[0];
00233     }
00234 
00235     protected function build_regexp($expression, $tokens) {
00236         // Replace to temp (and preg_quote() safe) placeholders
00237         foreach ($tokens as $token) {
00238             $expression = preg_replace('~' . preg_quote($token, '~') . '~', '#@@#@@#', $expression, 1);
00239         }
00240         // quote the expression
00241         $expression = preg_quote($expression, '~');
00242         // Replace all the placeholders
00243         $expression = preg_replace('~#@@#@@#~', '(.*)', $expression);
00244         return '~' . $expression . '~';
00245     }
00246 }
 All Data Structures Namespaces Files Functions Variables Enumerations