Xataface  2.0alpha2
Xataface Application Framework
 All Data Structures Namespaces Files Functions Variables Groups Pages
copy_replace.php
Go to the documentation of this file.
1 <?php
21 /*
22  * An action to copy a set of records and/or replace the values in specific
23  * fields of the records.
24  *
25  * @author Steve Hannah
26  * @created February 9, 2007
27  *
28  */
29 import('Dataface/QuickForm.php');
31  var $message = "";
32  var $renderer = null;
33  var $form;
34  var $dummyForms=array();
35 
36  function __construct(){
37  $this->message = df_translate('actions.copy_replace.default_success_message',"Records successfully updated.");
38  }
39 
40  function handle(&$params){
42  $query =& $app->getQuery();
43  $table =& Dataface_Table::loadTable($query['-table']);
44 
45 
46  $records = df_get_selected_records($query);
47  if ( count($records) == 0 ){
48  unset($records);
49  $q = $query;
50  $q['-start'] = 0;
51  $q['-limit'] = 9999;
52  $records =& df_get_records_array($query['-table'], $q);
53  }
54 
55 
56  // Now we find out a few things, like whether we're doing a related record
57  // list or the real list
58  $fields = $this->getFieldsForRecord($records[0]);
59 
60 
61  $field_options = array(0=>df_translate('actions.copy_replace.options.select_field_to_change','Select field to change...'));
62  foreach ($fields as $field){
63  $field_options[$field['name']] = $field['widget']['label'];
64  }
65 
66 
67 
68 
69 
70 
71  $this->form = new HTML_QuickForm('copy_replace_form', 'POST');
72  $form =& $this->form;
73  $this->addFields($form, $fields);
74 
75 
76  // Add the submit button and extra checkbox for copy
77  $form->addElement('hidden', '-copy_replace:fields');
78  $el =& $form->addElement('hidden', '-copy_replace:copy');
79  if ( @$query['--copy']) {
80  $form->setDefaults(array('-copy_replace:copy'=>1));
81  $message = df_translate('actions.copy_replace.copy_message',
82 <<<END
83  This form allows you to copy the selected records and update the
84  values of particular fields in the copies.
85 END
86 );
87  $title = df_translate('actions.copy_replace.copy_form_title',"Copy Records Form");
88 
89  $warning = df_translate('actions.copy_replace.copy_warning_message',
90 <<<END
91  Proceeding with this action will make copies of all selected records.
92  Use caution and care when using this form.
93 END
94 );
95  } else {
96  $message = df_translate('actions.copy_replace.update_message',
97 <<<END
98  This form allows you to perform batch updates on all of the selected
99  records. Use the form below to specify values to be placed in
100  any field.
101 END
102 );
103  $warning = df_translate('actions.copy_replace.update_warning_message',
104 <<<END
105  Proceeding with this action will update ALL selected records. You may not be able to undo these changes. Use caution
106  and care when using this form.
107 END
108 );
109  $title = df_translate('actions.copy_replace.update_form_title',"Find/Replace Form");
110 
111  }
112  foreach ($query as $key=>$val){
113  $res = $form->addElement('hidden',$key);
114  $form->setDefaults(array($key=>$val));
115  }
116 
117  $form->addElement('hidden', '-copy_replace:submit');
118  $form->setDefaults(array('-copy_replace:submit'=>1));
119 
120  $submit =& $form->addElement('submit', '-copy_replace:submit_btn', df_translate(
121  'actions.copy_replace.submit_label',
122  'Perform Update Now'
123  ));
124 
125 
126 
127 
128  if ( @$_POST['-copy_replace:submit'] and $form->validate() ){
129  $res = $form->process(array(&$this, 'process'), true);
130  if ( !PEAR::isError($res) ){
131  $q = array();
132  foreach ( array_keys($query) as $key){
133  // Remove extra copy/replace keys before forwarding
134  if ( strstr($key,'-copy_replace:') == $key or strstr($key, '-copy_replace_form:') == $key){
135  $q[$key] = null;
136  }
137  }
138 
139  if ( isset($query['-from']) ){
140  $q['-action'] = $query['-from'];
141  unset($q['-from']);
142  }
143  else $q['-action']= 'list';
144 
145  $url = $app->url($q);
146  $app->redirect($url.'&--msg='.urlencode($this->message));
147  }
148  }
149 
150 
151  $form->accept($this->renderer);
152  $out = $this->renderer->toHtml();
153 
155  $jt->import('xataface/copy_replace.js');
156 
157  df_display( array('title'=>$title, 'message'=>$message, 'warning'=>$warning,'records'=>$records, 'columns'=>$this->getKeysForRecord($records[0]), 'form'=>$out, 'context'=>&$this, 'field_options'=>$field_options), 'copy_replace.html');
158  return;
159 
160 
161  }
162 
163 
164 
166  if ( isset($this->dummyForms[$tablename]) ){
167  return $this->dummyForms[$tablename];
168  } else {
169  $this->dummyForms[$tablename] = new Dataface_QuickForm($tablename);
170  return $this->dummyForms[$tablename];
171  }
172  }
173 
174  function addFields(&$form, &$fields){
175 
177  $query =& $app->getQuery();
178  $this->renderer =& $form->defaultRenderer();
179 
180  foreach (array_keys($fields) as $fieldname){
181  if ( $fields[$fieldname]['widget']['type'] == 'hidden' ) continue;
182  $builder =& $this->getTableForm($fields[$fieldname]['tablename']);
183  $el = $builder->_buildWidget($fields[$fieldname]);
184  $el->setName('-copy_replace_form:replace['.$el->getName().']');
185  $form->addElement($el);
186  ob_start();
187  df_display(array('fieldname'=>$fieldname, 'field'=>&$fields[$fieldname], 'table'=>&$table), 'copy_replace_quickform_element_template.html');
188  $tpl = ob_get_contents();
189  ob_end_clean();
190  $this->renderer->setElementTemplate($tpl, $el->getName());
191  unset($builder);
192 
193  }
194  //$form->accept($this->renderer);
195  }
196 
197  function getFieldsForRecord(&$record){
198  if ( is_a($record, 'Dataface_Record') ){
199  $fields = $record->_table->fields();
200  foreach ($fields as $k=>$f){
201  if ( @$f['visibility']['update'] == 'hidden' ){
202  unset($fields[$k]);
203  }
204  }
205  return $fields;
206  } else if ( is_a($record, 'Dataface_RelatedRecord') ){
207  $fields = array();
208  $fieldnames = $record->_relationship->_schema['short_columns'];
209  foreach ($fieldnames as $fieldname){
210  $t =& $record->_relationship->getTable($fieldname);
211  $fields[$fieldname] =& $t->getField($fieldname);
212  if ( @$fields[$fieldname]['visibility']['update'] == 'hidden' ){
213  unset($fields[$fieldname]);
214  }
215  unset($t);
216  }
217  return $fields;
218  }
219  }
220 
221  function getKeysForRecord(&$record){
222  if ( is_a($record, 'Dataface_Record') ){
223  return $record->_table->keys();
224  } else if ( is_a($record, 'Dataface_RelatedRecord') ){
225  $r =& $record->toRecord();
226  return $r->_table->keys();
227 
228  }
229  }
230 
231 
232  function process($values){
234  import('Dataface/CopyTool.php');
235  $copyTool =& Dataface_CopyTool::getInstance();
236  $query =& $app->getQuery();
237  //if ( @$values['-copy_replace:copy'] ){
238 
239  //}
240 
241  $orig_replacements = $values['-copy_replace_form:replace'];
242  $update_fields = explode('-',$values['-copy_replace:fields']);
243  //print_r($update_fields);
244  $replacements = array();
245  foreach($update_fields as $fld){
246  if ( !$fld ) continue;
247  $replacements[$fld] = $orig_replacements[$fld];
248 
249  }
250 
251 
252 
253  $blanks = @$_POST['-copy_replace:blank_flag'];
254  if ( !$blanks ) $blanks = array();
255  foreach ($blanks as $key=>$val){
256  if ( $val ){
257  $replacements[$key] = null;
258  }
259  }
260 
261 
262  if ( !is_array($replacements) ){
263  return PEAR::raiseError(df_translate(
264  'actions.copy_replace.no_fields_selected_to_change',
265  "No fields were selected to change."
266  ));
267  }
268  $records = df_get_selected_records($query);
269  if (count($records) == 0 ) {
270  $q = $query;
271  $q['-limit'] = 99999;
272  $q['-skip'] = 0;
273  $records =& df_get_records_array($q['-table'], $q);
274  }
275 
276  $fields = $this->getFieldsForRecord($records[0]);
277 
278 
279 
280  $dummyForm =& $this->getTableForm($query['-table']);
281  foreach ($replacements as $key=>$val){
282  $dummyForm =& $this->getTableForm($fields[$key]['tablename']);
283  if ( strpos($val,'=') === 0 ){
284  // This is a calculated change so we don't try to push the value
285  // we'll let it go through
286  continue;
287  }
288  $val = $dummyForm->pushValue($key, $metaValues, $this->form->getElement('-copy_replace_form:replace['.$key.']'));
289  //echo $val;//));
290  //
291  if ( $val === '' and !@$blanks[$key]){
292  unset($replacements[$key]);
293  } else {
294  $replacements[$key] = $val;
295  }
296  unset($dummyForm);
297  }
298 
299 
300  $warnings = array();
301  $messages = array();
302  foreach ($records as $record){
303  if ( @$values['-copy_replace:copy'] ){
304  // We are performing a copy.
305  $res = $copyTool->copy($record, $replacements);
306  if ( PEAR::isError($res) ){
307  $warnings[] = $res;
308 
309  } else {
310  $messages[] = sprintf(
311  df_translate(
312  'actions.copy_replace.successfully_copied_record_x_as_record_y',
313  "Successfully copied record '%s' as record '%s'"
314  ),
315  $record->getTitle(),
316  $res->getTitle()
317  );
318  }
319  $warnings = array_merge($warnings, $copyTool->warnings);
320 
321  } else {
322  if ( !$record->checkPermission('edit') ){
323  $warnings[] = Dataface_Error::permissionDenied(
324  sprintf(
325  df_translate(
326  'actions.copy_replace.could_not_update_record_x_insufficient_permissions',
327  "Could not update record '%s' because of insufficient permissions."
328  ),
329  $record->getTitle()
330  )
331  );
332  continue;
333  }
334  $failed = false;
335  foreach ($replacements as $key=>$val){
336  if ( !$record->checkPermission('edit', array('field'=>$key)) ){
337  $warnings[] = Dataface_Error::permissionDenied(
338  sprintf(
339  df_translate(
340  'actions.copy_replace.could_not_update_record_x_insufficient_permissions_on_field_y',
341  "Could not update record '%s' because of insufficient permissions on field '%s'."
342  ),
343  $record->getTitle(),
344  $key
345  )
346  );
347  $failed = true;
348  }
349  }
350  if ( $failed ) continue;
351  foreach ($replacements as $k=>$v){
352 
353  if ( strpos($v,'=') === 0 ){
354  $replacements[$k] = $copyTool->evaluate($v, $k, $record);
355  }
356  }
357  $record->setValues($replacements);
358  $res = $record->save();
359  if ( PEAR::isError($res) ){
360  $warnings[] = $res;
361  } else {
362  $messages[] = sprintf(
363  df_translate(
364  'actions.copy_replace.successfully_updated_title',
365  "Successfully updated '%s'"
366  ),
367  $record->getTitle()
368  );
369  }
370  }
371  unset($record);
372  }
373  if ( @$values['-copy_replace:copy'] ){
374  $action = 'copied';
375  } else {
376  $action = 'updated';
377  }
378  $this->message = sprintf(
379  df_translate(
380  'actions.copy_replace.x_records_y_successfully_count_warnings',
381  '%d records %s successfully. %d warnings.'
382  ),
383  count($messages),
384  $action,
385  count($warnings)
386  );
387 
388  //$this->message = count($messages).' records '.$action.' successfully. '.count($warnings).' warnings.';
389  if ( count($warnings) ) {
390  $warning_msgs = array();
391  foreach ($warnings as $warning){
392  $warning_msgs[] = $warning->getMessage();
393  }
394 
395  } else {
396  $warning_msgs = array();
397  }
398  //print_r($warning_msgs);
399  $this->message .= '<br>'.implode('<br>', $warning_msgs);
400  return true;
401 
402 
403 
404  }
405 
406 }
407 
408 ?>