Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
bodycopy_table_edit_fns.inc
1 <?php
17 require_once SQ_CORE_PACKAGE_PATH.'/bodycopy/bodycopy_container/bodycopy_container_edit_fns.inc';
18 
31 {
32 
33 
38  function __construct()
39  {
40  parent::__construct();
41 
42  }//end __construct()
43 
44 
54  public function paintBackendJsData(Bodycopy_Table $asset, $prefix)
55  {
56  $table_rows = $asset->attr('rows');
57  $table_attributes = $asset->attr('attributes');
58  $table_attributes['identifier'] = $asset->name;
59  $max_cols = $this->maxCols($table_rows);
60  ?>
61  case <?php echo $asset->id?> :
62 
63  switch (rowid) {
64  <?php
65  for ($i = 0; $i < count($table_rows); $i++) {
66  ?>
67  case <?php echo $i?> :
68  switch (cellid) {
69  <?php
70  if (isset($table_rows[$i]['cells'])) {
71  for ($x = 0; $x < count($table_rows[$i]['cells']); $x++) {
72  if (isset($table_rows[$i]['cells'][$x])) {
73  $table_rows[$i]['cells'][$x]->printBackendJsData($x);
74  }
75  }
76  }
77  ?>
78 
79  default :
80  retVal["attributes"] = '<?php echo var_serialise($table_rows[$i]['attributes'], TRUE)?>';
81 
82  }//end switch cellid
83  break;
84  <?php
85  }
86  ?>
87 
88  default :
89  retVal["attributes"] = '<?php echo var_serialise($table_attributes, TRUE)?>';
90  retVal["num_cols"] = <?php echo (int) $max_cols?>;
91  retVal["num_rows"] = <?php echo count($table_rows)?>;
92 
93  }//end switch rowid
94 
95  break;
96  <?php
97 
98  }//end paintBackendJsData()
99 
100 
111  public function paintGenericBackend(Asset $bodycopy, Backend_Outputter $o, $prefix)
112  {
113  // If the parent bodycopy class is itself, fudge the containers array
114  // so that the proper stuff gets drawn when putting out the javascript
115  // to edit.
116  if ($bodycopy instanceof Bodycopy_Table) {
117  $containers = Array(Array('minorid'=>$bodycopy->id, 'minor_type_code'=>'bodycopy_table'));
118  } else {
119  $containers = $GLOBALS['SQ_SYSTEM']->am->getLinks($bodycopy->id, SQ_LINK_TYPE_2, 'bodycopy_container', FALSE);
120  }
121 
122  ?>
123  <script language="JavaScript" src="<?php echo sq_web_path('data').'/asset_types/bodycopy/js/bodycopy_edit_tables.js'?>"></script>
124 
125  <script language="JavaScript" type="text/javascript">
126  function serialise_table(bodycopy_name, bodycopy_data, tableid, rowid, cellid) {
127  var form = document.main_form;
128  if (!bodycopy_saved[bodycopy_name] && bodycopy_name != null) {
129  bodycopy_saved[bodycopy_name] = new Object();
130  }
131 
132  if (tableid != null) {
133  if (!bodycopy_saved[bodycopy_name][tableid]) {
134  bodycopy_saved[bodycopy_name][tableid] = new Object();
135  }
136 
137  if (rowid != null) {
138  if (!bodycopy_saved[bodycopy_name][tableid]['rows']) {
139  bodycopy_saved[bodycopy_name][tableid]['rows'] = new Object();
140  }
141  if (!bodycopy_saved[bodycopy_name][tableid]['rows'][rowid] && rowid != null) {
142  bodycopy_saved[bodycopy_name][tableid]['rows'][rowid] = new Object();
143  }
144  if (cellid != null) {
145  if (!bodycopy_saved[bodycopy_name][tableid]['rows'][rowid]['cells']) {
146  bodycopy_saved[bodycopy_name][tableid]['rows'][rowid]['cells'] = new Object();
147  }
148  bodycopy_saved[bodycopy_name][tableid]['rows'][rowid]['cells'][cellid] = bodycopy_data;
149  } else {
150  // no cellid means that we are setting row attributes
151  bodycopy_saved[bodycopy_name][tableid]['rows'][rowid]['attributes'] = bodycopy_data['attributes'];
152  }//end if cellid
153 
154  } else {
155  // no rowid means that we are settign the table attributes
156  bodycopy_saved[bodycopy_name][tableid]['attributes'] = bodycopy_data['attributes'];
157  }//end if rowid
158 
159  }//end if tableid
160 
161  form.elements['bodycopy_saved[' + bodycopy_name + '][' + tableid + ']'].value = var_serialise(bodycopy_saved[bodycopy_name][tableid]);
162  }//end serialise_table()
163 
164 
165  // general fn that the generic include fns can use to get data to use
166  function get_bodycopy_current_table_data(bodycopy_name, tableid, rowid, cellid) {
167  if (tableid == null) tableid = -1;
168  if (rowid == null) rowid = -1;
169  if (cellid == null) cellid = -1;
170  return bodycopy_current_data[bodycopy_name].get_table_data(tableid, rowid, cellid);
171  }
172 
173 
174  function get_bodycopy_<?php echo $prefix?>_current_table_data(tableid, rowid, cellid) {
175  retVal = new Object();
176 
177  switch (tableid) {
178  <?php
179  // if we have tables get them to print the js data they need
180  $i = 0;
181  if (count($containers)) {
182  foreach ($containers as $container_data) {
183  if ($container_data['minor_type_code'] != 'bodycopy_table') {
184  continue;
185  }
186  $table = $GLOBALS['SQ_SYSTEM']->am->getAsset($container_data['minorid'], $container_data['minor_type_code']);
187  $table_edit = $table->getEditFns();
188  $table_edit->paintBackendJsData($table, $prefix, $i);
189  $i++;
190  }
191  }
192  ?>
193  default :
194  retVal["num_containers"] = <?php echo count($containers); ?>;
195 
196  }//end switch tableid
197 
198 
199  // check if this piece of data has been changed before
200  // if it has, return the changed version, not the original
201  if (tableid != -1) {
202  if (rowid != -1) {
203  if (cellid != -1) {
204  if (bodycopy_saved &&
205  bodycopy_saved["<?php echo $prefix?>"] &&
206  bodycopy_saved["<?php echo $prefix?>"][tableid] &&
207  bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"] &&
208  bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"][rowid] &&
209  bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"][rowid]["cells"] &&
210  bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"][rowid]["cells"][cellid]) {
211  for (var key in bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"][rowid]["cells"][cellid]) {
212  retVal[key] = var_serialise(bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"][rowid]["cells"][cellid][key]);
213  }
214  }
215  return retVal;
216  } else {
217  // editing row properties
218  if (bodycopy_data_exists(new Array('<?php echo $prefix?>', tableid, 'rows', rowid, 'attributes'))) {
219  retVal["attributes"] = var_serialise(bodycopy_saved["<?php echo $prefix?>"][tableid]["rows"][rowid]["attributes"]);
220  return retVal;
221  }
222  }
223  } else {
224  // editing table properties
225  if (bodycopy_data_exists(new Array('<?php echo $prefix?>', tableid, 'attributes'))) {
226  retVal ["attributes"] = var_serialise(bodycopy_saved["<?php echo $prefix?>"][tableid]["attributes"]);
227  return retVal;
228  }
229  }
230  }
231 
232  return retVal;
233  }//end get_bodycopy_<?php echo $prefix?>_current_table_data()
234 
235 
236  // set reference so generic fn can be called above
237  bodycopy_current_data["<?php echo $prefix?>"].get_table_data = get_bodycopy_<?php echo $prefix?>_current_table_data;
238  </script>
239 
240  <?php
241 
242  }//end paintGenericBackend()
243 
244 
255  public function paint(Bodycopy_Table $asset, $editing=FALSE, $generating=FALSE)
256  {
257  $table_rows = $asset->attr('rows');
258  $table_attributes = $asset->attr('attributes');
259 
260  $attribute_list = '';
261  $bgimage = '';
262 
263  for (reset($table_attributes); $name = key($table_attributes); next($table_attributes)) {
264  $val = $table_attributes[$name];
265  if ($val == '') continue;
266  if ($name == 'disable_keywords') continue;
267  if ($name == 'background') {
268  $file = $GLOBALS['SQ_SYSTEM']->am->getAsset($val);
269  if ($file->id) $bgimage = $file->getURL();
270  continue;
271  }
272  $attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
273  }
274 
275  // Now add the ID of the table
276  $val = clean_div_attribute($asset->attr('name'));
277  if (!empty($val)) {
278  $attribute_list .= ' '.'id="'.$val.'"';
279  }
280 
281  echo "\n<table{$attribute_list}>\n";
282 
283  for ($i = 0; $i < count($table_rows); $i++) {
284  $attribute_list = '';
285  foreach ($table_rows[$i]['attributes'] as $name => $val) {
286  if ($val == '') continue;
287  $attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
288  }
289 
290  echo "\t<tr{$attribute_list}>\n";
291  // now print the cell contents
292  for ($x = 0; $x < count($table_rows[$i]['cells']); $x++) {
293  $table_rows[$i]['cells'][$x]->paint($asset, '', $editing, $generating);
294  }
295  echo "\t</tr>\n";
296  }
297 
298  echo "</table>\n";
299 
300  return TRUE;
301 
302  }//end paint()
303 
304 
315  public function paintContainer(Bodycopy_Table $asset, Backend_Outputter $o, $prefix)
316  {
317  if (!parent::paintContainer($asset, $o, $prefix)) {
318  return FALSE;
319  }
320 
321  $table_rows = $asset->attr('rows');
322  $table_attributes = $asset->attr('attributes');
323 
324  $attribute_list = '';
325  $popup_attribute_list = '';
326  $bgimage = '';
327  $dir_attribute = '';
328 
329  if (!empty($table_attributes)) {
330  for (reset($table_attributes); $name = key($table_attributes); next($table_attributes)) {
331  $val = $table_attributes[$name];
332  if ($val == '') continue;
333  if ($name == 'background') {
334  $file = $GLOBALS['SQ_SYSTEM']->am->getAsset($val);
335  if ($file->id) {
336  $popup_attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $file->attr('name')).'"';
337  }
338  $bgimage = $file->getURL();
339  continue;
340  }
341  $popup_attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
342  // if this is the width and the value isn't a percentage,
343  // then add 20 to it for the icons in the left column
344  if ($name == 'width' && !strstr($val, '%')) {
345  $val = (int) $val + 20;
346  }
347  if ($name == 'dir') $dir_attribute = $val;
348  $attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
349  }
350  }
351 
352  // set the tmp variable storing dir attribute of whole table
353  if (!empty($dir_attribute)) {
354  $this->_tmp['dir_attr'] = $dir_attribute;
355  }
356 
357  // need to find out if there's any colspans used at all. We can't handle
358  // column reshuffles if there is.
359  $colspans_in_row = FALSE;
360  for ($i = 0; $i < count($table_rows); $i++) {
361  for ($x = 0; $x < count($table_rows[$i]['cells']); $x++) {
362  if ($table_rows[$i]['cells'][$x]->colspan() > 1) {
363  $colspans_in_row = TRUE;
364  break;
365  }
366  }
367  if ($colspans_in_row) break;
368  }
369 
370  // require library functions needed for drawing the bodycopy
371  $type_info = $GLOBALS['SQ_SYSTEM']->am->getTypeInfo('bodycopy');
372 
373  ?>
374  <table<?php echo $attribute_list?> background="<?php echo $bgimage?>" border="0" cellpadding="0" cellspacing="0" style="width:100%;">
375 
376  <?php
377 
378  // For each defined cell, we're going to draw a special cell table
379  // with all the extra stuff around it. This lets each cell have
380  // proper row and colspan stuff in the editing interface.
381  $num_rows = count($table_rows);
382  for ($i = 0; $i < $num_rows; $i++) {
383  $attribute_list = '';
384  foreach ($table_rows[$i]['attributes'] as $name => $val) {
385  if ($val == '') continue;
386  $attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
387  }
388  ?>
389 
390  <tr<?php echo $attribute_list?>>
391  <?php
392  $num_cols = count($table_rows[$i]['cells']);
393  for ($x = 0; $x < $num_cols; $x++) {
394  $cell = $table_rows[$i]['cells'][$x];
395  ?>
396  <td valign="top" colspan="<?php echo $cell->colspan(); ?>" style="border: 1px dashed #C0C0C0;">
397  <?php
398  // when painting a cell, it needs to know if there's more than 1 row or column too for drawing
399  // the delete row/col buttons
400  $this->_paintEditingCell($asset, $prefix, $x, $i, $table_rows[$i]['cells'][$x], $num_cols > 1, $num_rows > 1, !$colspans_in_row);
401  ?>
402  </td>
403  <?php
404  }//end for (each cell)
405  ?>
406  </tr>
407 
408  <?php
409  }//end for
410 
411  ?>
412  </table>
413  <?php
414 
415  return TRUE;
416 
417  }//end paintContainer()
418 
419 
444  protected function _paintEditingCell(Bodycopy_Table $asset, $prefix, $x, $i, &$cell, $multiCol, $multiRow, $colReorder)
445  {
446  $attribute_list = '';
447  $table_rows = $asset->attr('rows');
448  $dir_attribute = '';
449 
450  foreach ($table_rows[$i]['attributes'] as $name => $val) {
451  if ($val == '') continue;
452  $attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
453  if ($name == 'dir' && !empty($val)) {
454  $dir_attribute = $val;
455  }
456  }
457 
458  // set the dir attribute to one inherited from the whole table if there is no specified for row
459  if (empty($dir_attribute) && isset($this->_tmp['dir_attr'])) {
460  $dir_attribute = $this->_tmp['dir_attr'];
461  }
462 
463  ?>
464  <table cellspacing="0" cellpadding="0" width="100%" height="100%">
465  <tbody valign="top">
466  <tr style="background-color: White; height: 20px;">
467  <?php
468  // only print out the table prop edit icons if this is the first cell in the
469  // row and first row..
470  if ($x == 0) {
471  ?>
472  <td id="<?php echo $prefix.'_table_'.$asset->id;?>" style="width: 20px;border-bottom: 1px dashed #C0C0C0;border-right: 1px dashed #C0C0C0;">
473  <?php
474  if (($x+$i) == 0) {
475  $popup_attribute_list = '';
476  $table_attributes = $asset->attr('attributes');
477  if (!empty($table_attributes)) {
478  foreach ($table_attributes as $name => $val) {
479  if ($val == '') continue;
480  if ($name == 'background') continue;
481  $popup_attribute_list .= ' '.$name.'="'.str_replace('"', '&quot;', $val).'"';
482 
483  }
484  }
485 
486  $public_userid = $GLOBALS['SQ_SYSTEM']->am->getSystemAssetid('public_user');
487 
488  $public_read = FALSE;
489  if ($asset->status == SQ_STATUS_LIVE && $asset->readAccess(Array($public_userid))) {
490  $public_read = TRUE;
491  }
492  $status_name = get_status_description($asset->status);
493  $status_img = get_asset_status_icon($asset->status);
494  $desc = translate('content_type_tooltip_status').': '.$status_img.'<b>'.get_status_description($asset->status).'</b><br />';
495  $desc .= translate('content_type_tooltip_public').': <b>'.($public_read ? translate('yes') : translate('no')).'</b><br />';
496  $desc .= (($popup_attribute_list) ? translate('current_properties').':<br>'.$popup_attribute_list : '');
497  Bodycopy_Edit_Fns::printBodycopyIcon('bodycopy_edit_table_properties(\''.$prefix.'\', '.$asset->id.', '.(($asset->status & SQ_SC_STATUS_SAFE_EDITING) ? 'false' : 'true').');', translate('edit_properties', $asset->attr('name')), $desc, 'table_properties');
498 
499  } else {
500  echo '&nbsp;';
501  }
502  ?>
503  </td>
504  <?php
505  }//end if
506  ?>
507 
508  <td style="border-bottom: 1px dashed #C0C0C0;" id="<?php echo $prefix.'_cell_'.$asset->id.'_'.$i.'_'.$x; ?>">
509  <!-- These next 3 icons float across to the right side -->
510  <span style="float: right;">
511  <?php
512 
513  // prints backend status icons, e.g. htmltidy status
514  $cell->paintCellBackendStatusIcons($asset, $prefix, $asset->id, $i, $x);
515 
516  if ($i==0) {
517  if (($x+$i) == 0 && $multiCol && $colReorder) {
518  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_edit_table_col_order('$prefix', $asset->id);", translate('reoder_columns_question', $asset->attr('name')), '', 'reorder', '['.translate('reorder_columns').']');
519 
520  }
521 
522  // if there's more than one row, and we're on the first row, let the col be deleted.
523  if ($multiCol) {
524  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_delete_table_col('$prefix', $asset->id, $x);", translate('delete_column_question', ($x + 1)), '', 'delete', '['.translate('delete_column').']');
525  }
526 
527  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_insert_table_col('$prefix', $asset->id, $x, false);", translate('insert_new_column_on_right'), '', 'add', '['.translate('add_column').' >>]');
528  }
529 
530  ?> </span> <?php
531 
532  if ($i==0) {
533  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_insert_table_col('$prefix', $asset->id, $x, true);", translate('insert_new_column_on_left'), '', 'add', '[<< '.translate('add_column').']');
534  }
535  $cell->setDirAttr($dir_attribute);
536  $cell->paintCell($asset, $prefix, $asset->id, $i, $x);
537 
538  ?>
539  </td>
540  </tr>
541  <tr valign="top" height="100%" style="height: 100%;" <?php echo $attribute_list?>>
542  <?php
543  if ($x == 0) {
544  ?>
545  <td style="width: 20px;border-right: 1px dashed #C0C0C0;" id="<?php echo $prefix.'_row_'.$asset->id.'_'.$i?>" nowrap="nowrap">
546  <?php
547  if ($i == 0 && $multiRow) {
548  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_edit_table_row_order('$prefix', $asset->id);", translate('reorder_rows_question', $asset->attr('name')), '', 'reorder', '['.translate('reorder_rows').']');
549  }
550  echo '<br/>';
551  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_insert_table_row('$prefix', $asset->id,$i, true);", translate('insert_new_row_above'), '', 'add', '[^ '.translate('add_row').']');
552 
553  echo '<br/>';
554  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_edit_table_row_properties('$prefix', $asset->id,$i);", translate('edit_row_question', ($i + 1)), (($attribute_list) ? translate('current_properties').':<br>'.$attribute_list : ''), 'row_properties', '['.translate('edit_row').']');
555  if ($multiRow) {
556  echo '<br/>';
557  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_delete_table_row('$prefix', $asset->id, $i);", translate('delete_row_question', ($i + 1)), '', 'delete', '['.translate('delete_row').']');
558  }
559  echo '<br/>';
560  Bodycopy_Edit_Fns::printBodycopyIcon("bodycopy_insert_table_row('$prefix', $asset->id, $i, false);", translate('insert_new_row_below'), '', 'add', '[v '.translate('add_row').']');
561  ?>
562  </td>
563  <?php
564  }
565  // a cell paints its own <td> tag
566  $cell->paint($asset, $prefix);
567  ?>
568  </tr>
569  </tbody>
570  </table>
571 
572  <?php
573 
574  }//end _paintEditingCell()
575 
576 
591  public function processContainer(Bodycopy_Table $asset, Backend_Outputter $o, $prefix, $bc_action, $bc_name, Array $bc_data, Array $bc_saved)
592  {
593  $updated = parent::processContainer($asset, $o, $prefix, $bc_action, $bc_name, $bc_data, $bc_saved);
594 
595  // update the rows
596  $rows_updated = FALSE;
597  $rows = $asset->attr('rows');
598 
599 
600  for ($rowid = 0; $rowid < count($rows); $rowid++) {
601  if (!empty($bc_saved[$prefix][$asset->id]['rows'][$rowid]['attributes'])) {
602  // save any changed row attributes
603  foreach ($bc_saved[$prefix][$asset->id]['rows'][$rowid]['attributes'] as $name => $value) {
604  $name = strtolower($name);
605  if (!isset($rows[$rowid]['attributes'][$name]) || $rows[$rowid]['attributes'][$name] != $value) {
606  $rows[$rowid]['attributes'][$name] = $value;
607  $rows_updated = TRUE;
608  }
609  }
610  }
611 
612  // only update if we are the table row that submitted the form
613  if ((!empty($bc_data['rowid']) && $bc_data['rowid'] == $rowid && $prefix == $bc_name) || isset($bc_saved[$prefix][$asset->id]['rows'][$rowid])) {
614 
615  $counter = 0;
616  $colspan_todo = Array();
617 
618  // check to see if any cells from this row need their colspans changed
619  if (isset($bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'])) {
620  foreach ($bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'] as $cellid => $cell_data) {
621 
622  if (isset($rows[$rowid]['cells'][$cellid])) {
623 
624  $current_span = $rows[$rowid]['cells'][$cellid]->colspan();
625  $colspaning = $cell_data['attributes']['colspan'];
626 
627  // if the current span is '1' and the new span is '' then a cell is being created
628  // so we dont want to do anything
629  if ($current_span == 1 && trim($colspaning) == '') {
630  $colspaning = $current_span;
631  }
632 
633  // if the user left colspan blank, dont change anything
634  if (trim($colspaning) == '') {
635  $colspaning = $current_span;
636  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = $current_span;
637  }
638 
639  // if the user entered a negative colspan - or '0', we can assume they want a colspan of '1'
640  if (intval($colspaning) <= 0) {
641  $colspaning = 1;
642  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = 1;
643  }
644  } else {
645  $colspaning = 0;
646  $current_span = 0;
647  }
648 
649  if ($colspaning != $current_span) {
650  // put this colspan into a todo list that we will do later
651  $colspan_todo[$counter]['cell'] = $cellid;
652  $colspan_todo[$counter]['colspaning'] = $colspaning;
653  $colspan_todo[$counter]['current_span'] = $current_span;
654  $counter++;
655  }
656  }//end foreach
657 
658  // doing the colspan thing
659  if (count($colspan_todo)) {
660 
661  foreach ($colspan_todo as $colspan) {
662 
663  $cellid = $colspan['cell'];
664  $colspaning = $colspan['colspaning'];
665  $current_span = $colspan['current_span'];
666 
667  // if the current span is '1' and the new span is '' then a cell is being created
668  // so we dont want to do anything
669  if ($current_span == 1 && trim($colspaning) == '') {
670  $colspaning = $current_span;
671  }
672 
673  // if the user left colspan blank, dont change anything
674  if (trim($colspaning) == '') {
675  $colspaning = $current_span;
676  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = $current_span;
677  }
678 
679  // if the user entered a negative colspan - or '0', we can assume they want a colspan of '1'
680  if (intval($colspaning) <= 0) {
681  $colspaning = 1;
682  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = 1;
683  }
684 
685 
686  if ($colspaning != $current_span) {
687 
688  // make sure there are sufficient cells to create the colspan
689  $spanable_cells = count($rows[$rowid]['cells']) - ($cellid +1);
690  $needed_cells = ($colspaning - $current_span);
691 
692  if ($spanable_cells < $needed_cells) {
693  // dont end up changing the colspan at all
694  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = $current_span;
695  } else {
696  if ($colspaning > $current_span && $spanable_cells >= 1) {
697  // check for more colspans first
698  $colspan_error = 0;
699  for ($i = ($cellid + 1); $i <= ($cellid + ($colspaning - $current_span)); $i++) {
700  if ($rows[$rowid]['cells'][$i]->colspan() > 1) {
701  $colspan_error = 1;
702  }
703  }
704  if ($colspan_error == 0) {
705  for ($i = ($cellid + 1); $i <= ($cellid + ($colspaning - $current_span)); $i++) {
706  if ($this->deleteCell($asset, $rows, $rowid, ($cellid+1), TRUE)) {
707  $rows_updated = TRUE;
708  } else {
709  // deleteCell failed
710  // dont end up changing the colspan at al
711  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = $current_span;
712  }
713  }
714  } else {
715  // we are trying to colspan into another colspan
716  // dont end up changing the colspan at all
717  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = $current_span;
718  }
719  } else if ($colspaning < $current_span) {
720  // decreasing the colspan
721 
722  for ($i = 0; $i < ($current_span - $colspaning); $i++) {
723  if ($this->insertCell($asset, $rows, $rowid, $cellid, FALSE, TRUE)) {
724  $rows_updated = TRUE;
725  } else {
726  // insertCell failed
727  // dont end up changing the colspan at al
728  $bc_saved[$prefix][$asset->id]['rows'][$rowid]['cells'][$cellid]['attributes']['colspan'] = $current_span;
729  }
730  }
731  }
732  }//end else
733 
734  }//end if
735 
736  }//end foreach
737 
738  }//end if we have colspans todo
739 
740  }//end if changing colspans
741 
742  }//end if we are the row that submitted the form
743 
744  // now update the cells
745  for ($i = 0; $i < count($rows[$rowid]['cells']); $i++) {
746  if ($rows[$rowid]['cells'][$i]->processCell($asset, $prefix, $asset->id, $rowid, $i, $bc_saved)) {
747  $rows_updated = TRUE;
748  }
749  }
750 
751  // only set the rows attributes if any of the rows (or cells within) have changed
752  if ($rows_updated) {
753  $asset->setAttrValue('rows',$rows);
754  $updated = TRUE;
755  }
756 
757  }//end for all rows
758 
759 
760  // check if there is anything for this table to do
761  $skip_table_editing = FALSE;
762  if (empty($bc_data) || !isset($bc_data['tableid']) || $bc_data['tableid'] != $asset->id) {
763  // no bodycopy data stuff relating to this table, so check the saved data
764  if (empty($bc_saved[$asset->id])) {
765  // there is nothing for us here
766  $skip_table_editing = TRUE;
767  }
768  }
769 
770 
771  // process any special actions if we are the table that submitted the form
772  if (!$skip_table_editing && !empty($bc_data) && $bc_data['tableid'] == $asset->id && $bc_name == $prefix) {
773  switch ($bc_action) {
774  case 'insert_table_row' :
775  if ($this->insertRow($asset, $bc_data['rowid'], $bc_data['before'])) {
776  $updated = TRUE;
777  }
778  break;
779 
780  case 'delete_table_row' :
781  if ($this->deleteRow($asset, $bc_data['rowid'])) {
782  $updated = TRUE;
783  }
784  break;
785 
786  case 'edit_table_row_order' :
787  if ($this->reorderRows($asset, $bc_data['row_order'])) {
788  $updated = TRUE;
789  }
790  break;
791 
792  case 'insert_table_column' :
793  if ($this->insertColumn($asset, $bc_data['colid'], $bc_data['before'])) {
794  $updated = TRUE;
795  }
796  break;
797 
798  case 'delete_table_column' :
799  if ($this->deleteColumn($asset, $bc_data['colid'])) {
800  $updated = TRUE;
801  }
802  break;
803 
804  case 'edit_table_col_order' :
805  if ($this->reorderColumns($asset, $bc_data['col_order'])) {
806  $updated = TRUE;
807  }
808  break;
809  }//end switch
810  }//end if - we are the table that submitted the form
811 
812  if ($updated) $this->generateContentFile($asset);
813  $this->_contentsUpdated($asset);
814  return $updated;
815 
816  }//end processContainer()
817 
818 
829  public function insertRow(Bodycopy_Table $asset, $rowid, $before=TRUE)
830  {
831  $rows = $asset->attr('rows');
832  $rowid = intval($rowid);
833 
834  // if the row is greater than the number of rows we have set it to the last on
835  if ($rowid > count($rows) - 1) {
836  $rowid = count($rows) - 1;
837  }
838  if ($rowid < 0) $rowid = 0;
839  $compareid = $rowid;
840 
841  // for the moment we will just use the number of columns that the one we are inserting
842  // before/after has
843  $num_cols = $this->maxCols($rows[$compareid], FALSE);
844 
845  // if they want to insert after the passed rowid what
846  // they really mean is to insert before the next rowid
847  if (!$before) $rowid++;
848 
849  // move all the rows up one position
850  for ($i = count($rows); $i > $rowid; $i--) {
851  $rows[$i] = $rows[$i - 1];
852  for ($x = 0; $x < count($rows[$i]['cells']); $x++) {
853  $rows[$i]['cells'][$x]->updateContentType($asset, $i, $x);
854  }
855  }
856 
857  if ($rowid <= $compareid) $compareid++;
858 
859  // now add the row
860  $rows[$rowid] = Array();
861  $rows[$rowid]['attributes'] = Array();
862  $rows[$rowid]['cells'] = Array();
863 
864  // create the cells and set their properties to
865  // the properties of the cells above/below
866  for ($i = 0; $i < count($rows[$compareid]['cells']); $i++) {
867  $rows[$rowid]['cells'][$i] = new Bodycopy_Table_Cell();
868  foreach ($rows[$compareid]['cells'][$i]->attributes as $name => $val) {
869  $rows[$rowid]['cells'][$i]->setAttribute($name,$val);
870  }
871  $rows[$rowid]['cells'][$i]->setContentType($asset, 'content_type_wysiwyg', $rowid, $i);
872  }
873 
874  $asset->setAttrValue('rows',$rows);
875  return TRUE;
876 
877  }//end insertRow()
878 
879 
889  public function deleteRow(Bodycopy_Table $asset, $rowid)
890  {
891  $rows = $asset->attr('rows');
892 
893  // make sure it exists
894  if (isset($rows[$rowid]) && count($rows) > 1) {
895 
896  // delete all the cells in the row so they can clean up
897  for ($i = 0; $i < count($rows[$rowid]['cells']); $i++) {
898  $rows[$rowid]['cells'][$i]->delete($asset);
899  }
900 
901  // move all the rows down one position
902  for ($i = $rowid; $i < count($rows) - 1; $i++) {
903  // let the cells know that they are moving to a new rowid
904  $rows[$i] = $rows[$i + 1];
905  for ($x = 0; $x < count($rows[$i]['cells']); $x++) {
906  $rows[$i]['cells'][$x]->updateContentType($asset, $i, $x);
907  }
908  }
909 
910  // remove the last element
911  array_pop($rows);
912 
913  $asset->setAttrValue('rows',$rows);
914  return TRUE;
915 
916  } else if (count($rows) == 1) {
917  return FALSE;
918  }
919 
920  return FALSE;
921 
922  }//end deleteRow()
923 
924 
934  public function reorderRows(Bodycopy_Table $asset, Array $row_order)
935  {
936  $rows = $asset->attr('rows');
937 
938  // if there ain't no changes, die
939  $changes = FALSE;
940  foreach ($row_order as $new_place => $old_place) {
941  $changes |= ($new_place != $old_place);
942  }
943  if (!$changes) return FALSE;
944 
945  // if there is a conflict in the number of rows, die
946  if (count($rows) != count(array_unique($row_order))) {
947  return FALSE;
948  }
949 
950  $new_array = Array();
951 
952  for ($i = 0; $i < count($row_order); $i++) {
953  for ($x = 0; $x < count($rows[$i]['cells']); $x++) {
954  $rows[$i]['cells'][$x]->updateContentType($asset, $row_order[$i], $x);
955  }
956  $new_array[$i] = $rows[$row_order[$i]];
957  }
958 
959  // now assign the new ordered array
960  $rows = $new_array;
961 
962  $asset->setAttrValue('rows',$rows);
963  return TRUE;
964 
965  }//end reorderRows()
966 
967 
977  public function reorderColumns(Bodycopy_Table $asset, Array $col_order)
978  {
979  // if there ain't no changes, die
980  $changes = FALSE;
981  foreach ($col_order as $new_place => $old_place) {
982  $changes |= ($new_place != $old_place);
983  }
984  if (!$changes) return FALSE;
985 
986  $rows = $asset->attr('rows');
987 
988  for ($r = 0; $r < count($rows); $r++) {
989  // if there is a conflict in the number of cells, die
990  if (count($rows[$r]['cells']) != count(array_unique($col_order))) {
991  return FALSE;
992  }
993 
994  $new_array = Array();
995  for ($i = 0; $i < count($col_order); $i++) {
996  $rows[$r]['cells'][$i]->updateContentType($asset, $r, $col_order[$i]);
997  $new_array[$i] = $rows[$r]['cells'][$col_order[$i]];
998  }
999  // now assign the new ordered array
1000  $rows[$r]['cells'] = $new_array;
1001  }
1002 
1003  $asset->setAttrValue('rows',$rows);
1004  return TRUE;
1005 
1006  }//end reorderColumns()
1007 
1008 
1019  public function insertColumn(Bodycopy_Table $asset, $cellid, $before=TRUE)
1020  {
1021  $rows = $asset->attr('rows');
1022 
1023  // we dont know how to do this ourselves, so just get
1024  // every row to insert a new cell and it can handle checking
1025  for ($r = 0; $r < count($rows); $r++) {
1026  if (!$this->insertCell($asset, $rows, $r, $cellid, $before)) {
1027  return FALSE;
1028  }
1029  }
1030 
1031  $asset->setAttrValue('rows',$rows);
1032  return TRUE;
1033 
1034  }//end insertColumn()
1035 
1036 
1046  public function deleteColumn(Bodycopy_Table $asset, $cellid)
1047  {
1048  $rows = $asset->attr('rows');
1049 
1050  // we dont know how to do this ourselves, so just get
1051  // every row to delete the cell and it can handle checking
1052  for ($r = 0; $r < count($rows); $r++) {
1053  if (!$this->deleteCell($asset, $rows, $r, $cellid)) {
1054  return FALSE;
1055  }
1056  }
1057 
1058  $asset->setAttrValue('rows',$rows);
1059  return TRUE;
1060 
1061  }//end deleteColumn()
1062 
1063 
1077  public function insertCell(Bodycopy_Table $asset, Array &$rows, $rowid, $cellid, $before=TRUE, $colspan=FALSE)
1078  {
1079  if (!$colspan) {
1080 
1081  // check for colspan's in this row - colspan's will muck things up
1082  $colspan_error = 0;
1083  $colspaning = 0;
1084  for ($i = 0; $i < count($rows[$rowid]['cells']); $i++) {
1085  if ($rows[$rowid]['cells'][$i]->colspan() > 1) {
1086  $colspan_error = 1;
1087  }
1088  }
1089  if ($colspan_error == 1) {
1090  // work out the correct cellid for the id passed in
1091  $real_cellid = 0;
1092  for ($i = 0; $i < count($rows[$rowid]['cells']); $i++) {
1093  if ($colspaning >= $cellid) break;
1094  $colspaning += intval($rows[$rowid]['cells'][$i]->colspan());
1095  if (intval($rows[$rowid]['cells'][$i]->colspan()) == 0) {
1096  $colspaning++;
1097  }
1098  if ($colspaning <= $cellid) {
1099  // havn't found the cell yet
1100  $real_cellid++;
1101  }
1102  }
1103 
1104  // lets try and find out how many cells are before the cell we are looking at
1105  $colspaning = 0;
1106  for ($i = 0; $i < $real_cellid; $i++) {
1107  $colspaning += intval($rows[$rowid]['cells'][$i]->colspan());
1108  if (intval($rows[$rowid]['cells'][$i]->colspan()) == 0) {
1109  $colspaning++;
1110  }
1111  }
1112 
1113  if ($real_cellid < 0) $real_cellid = 0;
1114 
1115  // now we have the real cellid, so we will be increasing the colspan of this cell
1116  // (if it has one) unless we are supposed to be inserting AFTER this cell or BEFORE
1117  // this cell
1118  // so lets check shall we?
1119 
1120  $dont_do_this = FALSE;
1121 
1122  // if the real cellid is found to be the same as the cellid, we have a special
1123  // situation where we have found the first cell in a colspan that has no
1124  // colspans before it on the row
1125  if ($cellid == $real_cellid) {
1126  if ($before) $dont_do_this = TRUE;
1127  } else {
1128  if ((($rows[$rowid]['cells'][$real_cellid]->colspan() + $colspaning) == ($cellid + 1)) && !$before) {
1129  $dont_do_this = TRUE;
1130  }
1131  }
1132 
1133  if ($cellid == 0 && $before) {
1134  $dont_do_this = TRUE;
1135  }
1136 
1137  $cellid = $real_cellid;
1138  if ($cellid < 0) $cellid = 0;
1139 
1140  // if this cell has colspan's already, we can just increase the colspan by 1
1141  if ($rows[$rowid]['cells'][$cellid]->colspan() > 1 && !$dont_do_this) {
1142  $colspaning = $rows[$rowid]['cells'][$cellid]->colspan() + 1;
1143  $rows[$rowid]['cells'][$cellid]->setAttribute('colspan', $colspaning);
1144  return TRUE;
1145  }
1146 
1147  }//end if colspan_error
1148  }//end if not colspan
1149 
1150  // if the cell is greater than the number of cells we have set it to the last on
1151  if ($cellid > count($rows[$rowid]['cells']) - 1) {
1152  $cellid = count($rows[$rowid]['cells']) - 1;
1153  }
1154  if ($cellid < 0) $cellid = 0;
1155  $compareid = $cellid;
1156 
1157  // if they want to insert after the passed cell what
1158  // they really mean is to insert before the next cell
1159  if (!$before) $cellid++;
1160 
1161  // move all the cells up one position
1162  for ($i = count($rows[$rowid]['cells']); $i > $cellid; $i--) {
1163  $rows[$rowid]['cells'][$i] = $rows[$rowid]['cells'][$i - 1];
1164  $rows[$rowid]['cells'][$i]->updateContentType($asset, $rowid, $i);
1165  }
1166 
1167  if ($cellid <= $compareid) $compareid++;
1168 
1169  // now add the cell
1170  $rows[$rowid]['cells'][$cellid] = new BodyCopy_Table_Cell();
1171 
1172  // now that the cell exists, set its properties to
1173  // the properties of the cell to the left/right
1174  foreach ($rows[$rowid]['cells'][$compareid]->attributes as $name => $val) {
1175  if (strtolower($name) == 'colspan') continue;
1176  $rows[$rowid]['cells'][$cellid]->setAttribute($name,$val);
1177  }
1178  $rows[$rowid]['cells'][$cellid]->setContentType($asset, 'content_type_wysiwyg', $rowid, $cellid);
1179 
1180  return TRUE;
1181 
1182  }//end insertCell()
1183 
1184 
1197  public function deleteCell(Bodycopy_Table $table, Array &$rows, $rowid, $cellid, $colspan=FALSE)
1198  {
1199  if (!$colspan) {
1200 
1201  // check for colspan's in this row - colspan's will muck things up
1202  $colspan_error = 0;
1203  $colspaning = 0;
1204  for ($i = 0; $i < count($rows[$rowid]['cells']); $i++) {
1205  if ($rows[$rowid]['cells'][$i]->colspan() > 1) {
1206  $colspan_error = 1;
1207  }
1208  }
1209 
1210  if ($colspan_error == 1) {
1211  // work out the correct cellid for the id passed in
1212  $real_cellid = 0;
1213  for ($i = 0; $i < count($rows[$rowid]['cells']); $i++) {
1214  if ($colspaning >= $cellid) break;
1215  $colspaning += intval($rows[$rowid]['cells'][$i]->colspan());
1216  if (intval($rows[$rowid]['cells'][$i]->colspan()) == 0) {
1217  $colspaning++;
1218  }
1219  if ($colspaning <= $cellid) {
1220  // havn't found the cell yet
1221  $real_cellid++;
1222  }
1223  }
1224 
1225  $cellid = $real_cellid;
1226 
1227  // if this cell has colspan's already, we can just reduce the colspan by 1
1228  if ($rows[$rowid]['cells'][$cellid]->colspan() > 1) {
1229  $colspaning = $rows[$rowid]['cells'][$cellid]->colspan() - 1;
1230  $rows[$rowid]['cells'][$cellid]->setAttribute('colspan', $colspaning);
1231  return TRUE;
1232  }
1233  }
1234  }//end if not colspanning
1235 
1236  // make sure cell exists
1237  if ($rows[$rowid]['cells'][$cellid] && count($rows[$rowid]['cells']) > 1) {
1238  // do any clean up
1239  if (!$rows[$rowid]['cells'][$cellid]->delete($table, $rowid, $cellid)) {
1240  return FALSE;
1241  }
1242 
1243  // move all the cells down one position
1244  for ($i = $cellid; $i < count($rows[$rowid]['cells']) - 1; $i++) {
1245  $rows[$rowid]['cells'][$i] = $rows[$rowid]['cells'][$i + 1];
1246  $rows[$rowid]['cells'][$i]->updateContentType($table, $rowid, $i);
1247  }
1248 
1249  // remove the last element
1250  array_pop($rows[$rowid]['cells']);
1251  return TRUE;
1252 
1253  } else if (count($this->cells) == 1) {
1254  return FALSE;
1255  }
1256 
1257  }//end deleteCell()
1258 
1259 
1269  public function maxCols($table_rows, $add_colspans=TRUE)
1270  {
1271  $max = 0;
1272  for ($i = 0; $i < count($table_rows); $i++) {
1273  $num = 0;
1274  if (empty($table_rows[$i]['cells'])) continue;
1275  for ($x = 0; $x < count($table_rows[$i]['cells']); $x++) {
1276  if ($add_colspans) {
1277  $num += $table_rows[$i]['cells'][$x]->colspan();
1278  } else {
1279  $num++;
1280  }
1281  }
1282  if ($max < $num) $max = $num;
1283  }
1284  return (int)$max;
1285 
1286  }//end maxCols()
1287 
1288 
1289 }//end class
1290 
1291 ?>