Xataface 2.0
Xataface Application Framework
Dataface/CopyTool.php
Go to the documentation of this file.
00001 <?php 
00002 
00003 class Dataface_CopyTool {
00004         var $warnings;
00005 
00006         public static function &getInstance(){
00007                 static $instance = 0;
00008                 if ( !is_object($instance) ){
00009                         $instance = new Dataface_CopyTool();
00010                 }
00011                 return $instance;
00012         }
00013         
00014         
00015         function evaluate($expr, $fieldname, Dataface_Record $record){
00016                 
00017                 // Check the field type first.  If this is a numeric field
00018                 // we evaluate with math
00019                 // If it is a string, we evaluate with string functions
00020                 
00021                 // Chop the leading '='
00022                 $expr = substr($expr,1);
00023                 
00024                 $table = $record->table();
00025                 if ( $table->isInt($fieldname) or $table->isFloat($fieldname) ){
00026                         // This field is a numeric field so we treat it like 
00027                         // a numeric operation
00028                         $oldval = $record->val($fieldname);
00029                         if ( !$oldval ) $oldval = 0;
00030                         $expr = preg_replace('/\$\$/', $oldval, $expr);
00031                         if ( preg_match('/^[\+\-\*\/]/', $expr) ){
00032                                 // If expression begins with an operation, we apply
00033                                 // the old value as the first operand of this
00034                                 // operation.
00035                                 $expr = $oldval.$expr;
00036                         }
00037                         
00038                         if ( !preg_match('/^[0-9\.\*\+\/\-\^\(\) ]+$/', $expr) ){
00039                                 throw new Exception("Invalid arithmetic expression.");
00040                         }
00041                         @eval('$expr='.$expr.';');
00042                         return $expr;
00043                                         
00044                         
00045                 } else if ( $table->isDate($fieldname) ){
00046                 
00047                         // This field is a date field so we treat it like a 
00048                         // date operation
00049                         $oldtime = strtotime($record->strval($fieldname));
00050                         return date($expr, $oldtime);
00051                 
00052                 } else {
00053                         // We assume it is a string
00054                         $oldval = $record->val($fieldname);
00055                         $expr = preg_replace('/\$\$/', $oldval, $expr);
00056                         return $expr;
00057                 
00058                 }
00059                 
00060         }
00061         
00062         function copy($record, $vals=array(), $force=true){
00063         
00064                 foreach ($vals as $k=>$v){
00065                         if ( strpos($v,'=') === 0  ){
00066                                 $vals[$k] = $this->evaluate($v, $k, $record);
00067                         }
00068                 }
00069         
00070                 $del = $record->_table->getDelegate();
00071                 if ( isset($del) and method_exists($del, 'beforeCopy') ){
00072                         $res = $del->beforeCopy($record, $vals);
00073                         if ( PEAR::isError($res) ){
00074                                 return $res;
00075                         }
00076                 }
00077                 $this->warnings = array();
00078                 // Step 1: Load the record - it has been passed
00079                 // Step 2: build sql query to copy the record
00080                 $query = $this->buildCopyQuery($record, $vals, $force);
00081                 if ( PEAR::isError($query) ){
00082                         return $query;
00083                 }
00084                 $res = df_query($query);
00085                 if ( !$res ){
00086                         return PEAR::raiseError("Failed to copy record '".$record->getTitle()."' due to an SQL error:".mysql_error());
00087                 }
00088                 if ( PEAR::isError($res) ) return $res;
00089                 
00090                 
00091                 $ret = null;
00092                 
00093                 if ( $auto_field_id = $record->_table->getAutoIncrementField()) {
00094                         $insert_id = df_insert_id();
00095                         $copied =& df_get_record($record->_table->tablename, array($auto_field_id=>$insert_id));
00096                         $ret = $copied;
00097                 } else {
00098                         $ret = new Dataface_Record($record->_table->tablename, array_merge($record->vals(), $vals));
00099                 }
00100                 
00101                 if ( isset($del) and method_exists($del, 'afterCopy')){
00102                         $res = $del->afterCopy($record, $ret);
00103                         if ( PEAR::isError($res) ){
00104                                 return $res;
00105                         }
00106                         
00107                 }
00108                 return $ret;
00109                 
00110         }
00111         
00127         function buildCopyQuery($record,$vals=array(), $force=true){
00128                 
00129                 $dummy = new Dataface_Record($record->_table->tablename, $vals);
00130                 if ( !$record->checkPermission('view') || !$dummy->checkPermission('edit') ){
00131                         return Dataface_Error::permissionDenied("Failed to copy record '".$record->getTitle()."' because of insufficient permissions.");
00132                 }
00133                 
00134                 $copy_fields = array_keys($record->_table->fields());
00135                 
00136                 // Go through each field and see if we have copy permission.
00137                 // Copy permission is two-fold: 1- make sure the source is viewable
00138                 //                                                              2- make sure the destination is editable.
00139                 $failed = false;
00140                 foreach ($copy_fields as $key=>$fieldname){
00141                         if ( !$record->checkPermission('view', array('field'=>$fieldname))
00142                                 || !$dummy->checkPermission('edit', array('field'=>$fieldname)) ){
00143                                 $this->warnings[] = Dataface_Error::permissionDenied("The field '$fieldname' could not be copied for record '".$record->getTitle()."' because of insufficient permissions.");
00144                                 unset($copy_fields[$key]);
00145                                 $failed = true;
00146                         }
00147                 }
00148                 
00149         
00150                 // If we are not forcing completion, any failures will result in cancellation
00151                 // of the copy.
00152                 if ( !$force and $failed ){
00153                         return Dataface_Error::permissionDenied("Failed to copy the record '".$record->getTitle()."' due to insufficient permissions on one or more of the columns.");
00154                 }
00155                 
00156                 // We don't copy auto increment fields.
00157                 $auto_inc_field = $record->_table->getAutoIncrementField();
00158                 if ( $auto_inc_field ){
00159                         $key = array_search($auto_inc_field, $copy_fields);
00160                         if ( $key !== false ) unset($copy_fields[$key]);
00161                 }
00162                 
00163                 // Now we can build the query.
00164                 $sql = array();
00165                 $sql[] = "insert into `".$record->_table->tablename."`";
00166                 $sql[] = "(`".implode('`,`', $copy_fields)."`)";
00167                 
00168                 $copy_values = array();
00169                 foreach ($copy_fields as $key=>$val){
00170                         if ( isset($vals[$val]) ){
00171                                 $copy_values[$key] = "'".addslashes($dummy->getSerializedValue($val))."' as `$val`";
00172                         } else {
00173                                 $copy_values[$key] = "`".$val."`";
00174                         }
00175                 }
00176                 $sql[] = "select ".implode(', ', $copy_values)." from `".$record->_table->tablename."`";
00177                 $qb = new Dataface_QueryBuilder($record->_table->tablename);
00178                 
00179                 $keys = array_keys($record->_table->keys());
00180                 $q = array();
00181                 foreach ($keys as $key_fieldname){
00182                         $q[$key_fieldname] = $record->strval($key_fieldname);
00183                 }
00184                 $where = $qb->_where($q);
00185                 $where = $qb->_secure($where);
00186                 $sql[] = $where;
00187                 return implode(' ', $sql);
00188                 
00189                 
00190         }
00191 }
 All Data Structures Namespaces Files Functions Variables Enumerations