Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
data_source_graph.inc
1 <?php
18 require_once SQ_CORE_PACKAGE_PATH.'/files/image/image.inc';
19 
31 class Data_Source_Graph extends Image
32 {
33 
38  var $allowed_extensions = Array( 'png');
39 
44  var $plotarea = NULL;
45 
46 
53  function Data_Source_Graph($assetid=0)
54  {
55  $this->_ser_attrs = TRUE;
56  $this->Image($assetid);
57 
58  }//end constructor
59 
60 
74  function create(&$link, $info=Array())
75  {
76  // make a dummy png file first
77  $this->makeGlobalSettingsPreview(TRUE);
78 
79  // fill $info array
80  $name = trim(strtolower(str_replace(' ', '_', $this->attr('title'))));
81  $info = Array(
82  'name' => $name.'.png',
83  'type' => 'image/png',
84  'path' => SQ_DATA_PATH.'/temp/'.$name.'.png',
85  'filename' => $name.'.png',
86  );
87  $this->_tmp['file_create_data'] = &$info;
88 
89  if ($name == '') {
90  trigger_localised_error('CORE0083', E_USER_WARNING, $GLOBALS['SQ_SYSTEM']->am->getTypeInfo($this->type(), 'name'));
91  return FALSE;
92  }
93  if (!$this->validFile($info)) return FALSE;
94 
95  // check that we are not going to have web path conflicts
96  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
97  $valid_names = make_valid_web_paths(Array($info['name']));
98  $name = array_shift($valid_names);
99 
100  // make sure the new web path is not already is use
101  $bad_paths = $GLOBALS['SQ_SYSTEM']->am->webPathsInUse($link['asset'], Array($name));
102  if (!empty($bad_paths)) {
103  trigger_localised_error('CORE0086', E_USER_WARNING, $name);
104  return FALSE;
105  }
106  $this->setAttrValue('name', $name);
107 
108  if (Asset::create($link)) {
109  return unlink($info['path']);
110  } else {
111  unlink($info['path']);
112  return FALSE;
113  }
114 
115  }//end create()
116 
117 
129  function _createAdditional(&$link)
130  {
131  // assetid will not be set if we are creating
132  if (!$this->id) return TRUE;
133 
134  // make the info array look like a result from getExistingFile()
135  $info = $this->_tmp['file_create_data'];
136 
137  if (!$this->validFile($info)) return FALSE;
138 
139  require_once SQ_INCLUDE_PATH.'/general_occasional.inc';
140  $name = current(make_valid_web_paths(Array(strtolower($info['name']))));
141 
142  // make sure the new web path is not already is use
143  if ($this->name != $name) {
144  $parents = $GLOBALS['SQ_SYSTEM']->am->getLinks($this->id, SQ_SC_LINK_SIGNIFICANT, '', NULL, 'minor');
145  for ($i = 0; $i < count($parents); $i++) {
146  $parent = $GLOBALS['SQ_SYSTEM']->am->getAsset($parents[$i]['majorid'], $parents[$i]['major_type_code']);
147  if (is_null($parent)) continue;
148  $bad_paths = $GLOBALS['SQ_SYSTEM']->am->webPathsInUse($parent, Array($name), $this->id);
149  if (!empty($bad_paths)) {
150  trigger_localised_error('CORE0055', E_USER_WARNING);
151  return FALSE;
152  }
153  }
154  }
155 
156  // create the destination directory, if necessary (NOTE that checking is internal for this)
157  create_directory($this->data_path);
158 
159  // copy over the new uploaded file
160  if (!copy($info['path'], $this->data_path.'/'.$name)) {
161  trigger_localised_error('CORE0036', E_USER_WARNING, $info['name'], $this->data_path.'/'.$name);
162  return FALSE;
163  }
164 
165  // set the graph file name to pass done() function
166  $this->_tmp['graph_file_name'] = Array('filename' => $this->data_path.'/'.$name);
167 
168  $existing = $this->getExistingFile();
169 
170  // set the name of the file to the newly uploaded one
171  $this->_tmp['uploading_file'] = FALSE;
172  $name_changed = $this->setAttrValue('name', $name);
173  if (!$this->saveAttributes()) {
174  trigger_localised_error('CORE0052', E_USER_WARNING);
175  return FALSE;
176  }
177  $asset->_tmp['uploading_file'] = FALSE;
178 
179  if (!$this->saveWebPaths(Array($name))) {
180  trigger_localised_error('CORE0054', E_USER_WARNING);
181  return FALSE;
182  }
183 
184  $em = $GLOBALS['SQ_SYSTEM']->getEventManager();
185  $em->broadcastEvent($this, 'ContentsUpdated');
186 
187  // Now we can call getExistingFile() function
188  $info = $this->getExistingFile();
189  if (!empty($info)) {
190  if (!$this->setAttrValue('width', $info['width'])) {
191  return FALSE;
192  }
193  if (!$this->setAttrValue('height', $info['height'])) {
194  return FALSE;
195  }
196  if (!$this->setAttrValue('size', $info['size'])) {
197  return FALSE;
198  }
199  }
200 
201  $GLOBALS['SQ_SYSTEM']->am->acquireLock($this->id, 'all');
202  if (!$this->saveAttributes()) {
203  trigger_localised_error('CORE0052', E_USER_WARNING);
204  return FALSE;
205  }
206  $GLOBALS['SQ_SYSTEM']->am->releaseLock($this->id, 'all');
207 
208  return TRUE;
209 
210  }//end _createAdditional()
211 
212 
219  function printBody()
220  {
221  $this->printImageTag();
222 
223  }//end printBody()
224 
225 
239  function printImageTag($alt='', $title='', $return=FALSE)
240  {
241  if ($title == '') {
242  $title = ($alt != '') ? $alt : $this->attr('title');
243  }
244  if ($alt == '') $alt = $this->attr('alt');
245 
246  $tag = '<img src="'.$this->getURL().'" width="'.$this->attr('width').'" height="'.$this->attr('height').'" alt="'.$alt.'" title="'.$title.'" />';
247  if ($return) return $tag;
248  echo $tag;
249 
250  }//end printImageTag()
251 
252 
261  function describeLink($linkid)
262  {
263  $link = $GLOBALS['SQ_SYSTEM']->am->getLinkById($linkid);
264  switch (strtolower($link['value'])) {
265  case 'data_source_for_graph' :
266  return (translate('data_source_asset_linked_to_graph').' '.$this->id);
267  break;
268  default :
269  return parent::describeLink($linkid);
270  break;
271  }
272 
273  }//end describeLink()
274 
275 
287  function paintBackend(&$o)
288  {
289  if (!isset($_REQUEST['preview_graph'])) {
290  return parent::paintBackend($o);
291  }
292 
293  switch ($_REQUEST['asset_ei_screen']) {
294 
295  case 'global_settings' :
296  // if count(datasets) >= 1, update the img file here
297  $datasets = $this->attr('datasets');
298  if (count($datasets) > 0 && $this->isGraphReady()) {
299  $this->getFinalGraph(TRUE);
300  }
301 
302  // global setting preview
303  $this->makeGlobalSettingsPreview(FALSE);
304  exit();
305 
306  case 'datasets' :
307  // update the img file here
308  $this->getFinalGraph(TRUE);
309 
310  // single plot preview
311  if (isset($_REQUEST['final_preview'])) {
312  $this->getFinalGraph();
313  } else {
314  // graph info is passed through $_POST var after serialization
315  // we need to pass them to makePlotSettingsPreview() function
316  $graph_info = unserialize(urldecode($_REQUEST['graph_info']));
317  $this->makePlotSettingsPreview($graph_info);
318  }
319  exit();
320 
321  default :
322  return parent::paintBackend($o);
323 
324  }//end switch
325 
326  }//end paintBackend()
327 
328 
329 //-- GRAPHS --//
330 
331 
341  function &getNewGraph()
342  {
343  require_once 'Image/Graph.php';
344 
345  $width = $this->attr('width');
346  $height = $this->attr('height');
347  $graph = Image_Graph::factory('graph', Array((int) $width, (int) $height));
348  $title = $this->attr('show_graph_title') ? $this->attr('title') : '';
349  if ($this->attr('show_legend')) {
350  $graph_ratio = 90;
351  } else {
352  $graph_ratio = 100;
353  }
354  if ($this->attr('graph_angle')) {
355  $graph->add(
356  Image_Graph::vertical(
357  Image_Graph::factory('title', Array($title, 12)),
358  Image_Graph::vertical(
359  $plotarea = Image_Graph::factory('plotarea'),
360  $legend = Image_Graph::factory('legend'),
361  $graph_ratio
362  ),
363  5
364  )
365  );
366  } else if (!$this->attr('graph_angle')) {
367  $param = Array(
368  'Image_Graph_Axis_Category',
369  'Image_Graph_Axis',
370  'horizontal',
371  );
372  $graph->add(
373  Image_Graph::vertical(
374  Image_Graph::factory('title', Array($title, 12)),
375  Image_Graph::vertical(
376  $plotarea = Image_Graph::factory('plotarea', $param),
377  $legend = Image_Graph::factory('legend'),
378  $graph_ratio - 1
379  ),
380  5
381  )
382  );
383  }
384  $plotarea->setAxisPadding(
385  Array(
386  'left' => (int) $this->attr('axis_left_padding'),
387  'right' => (int) $this->attr('axis_right_padding'),
388  'top' => (int) $this->attr('axis_top_padding'),
389  'bottom' => (int) $this->attr('axis_bottom_padding'),
390  )
391  );
392  $legend->setPlotarea($plotarea);
393 
394  // Background Color
395  $graph->setBackgroundColor($this->attr('background'));
396 
397  // Border Color
398  $graph->setBorderColor($this->attr('border_colour'));
399 
400  $x_axis_title_angle = ($this->attr('x_font_label_angle') ? 90 : 0);
401  $y_axis_title_angle = ($this->attr('y_font_label_angle') ? 90 : 0);
402 
403  $x_axis =& $plotarea->getAxis(IMAGE_GRAPH_AXIS_X);
404  $x_axis->setTitle($this->attr('x_set_title'), Array('size' => 13, 'angle' => $x_axis_title_angle));
405  $x_axis->setLabelInterval($this->attr('x_label_interval'));
406 
407  $y_axis =& $plotarea->getAxis(IMAGE_GRAPH_AXIS_Y);
408  $y_axis->setTitle($this->attr('y_set_title'), Array('size' => 13, 'angle' => $y_axis_title_angle));
409  $y_axis->setLabelInterval($this->attr('y_label_interval'));
410 
411  // setting up x-axis colour and title
412  $x_axis->setLineColor($this->attr('x_axis_colour'));
413 
414  // setting up font colour for x-axis
415  $x_axis_font =& $graph->addNew('Image_Graph_Font');
416  $x_axis_font->setSize(12);
417  $x_axis_font->setColor($this->attr('x_font_axis_colour'));
418  $x_axis->setFont($x_axis_font);
419  $x_axis->setFontAngle($this->attr('x_font_label_angle') ? 'vertical' : 'horizontal');
420 
421  // setting up y-axis colour and title
422  $y_axis->setLineColor($this->attr('y_axis_colour'));
423 
424  // setting up font colour for y-axis
425  $y_axis_font =& $graph->addNew('Image_Graph_Font');
426  $y_axis_font->setSize(12);
427  $y_axis_font->setColor($this->attr('y_font_axis_colour'));
428  $y_axis->setFont($y_axis_font);
429  $y_axis->setFontAngle($this->attr('y_font_label_angle') ? 'vertical' : 'horizontal');
430 
431  // set the reference to plotarea
432  $this->plotarea =& $plotarea;
433 
434  return $graph;
435 
436  }//end getNewGraph()
437 
438 
451  function getFinalGraph($to_file=FALSE)
452  {
453  // Turn off error level. PEAR Image package generates
454  // PHP 4 warning, which prevents printFroend() sending
455  // proper header information
456  $old_err_level = error_reporting(0);
457 
458  $graph = $this->getNewGraph();
459  $datasets = $this->attr('datasets');
460 
461  $plot_order = $this->attr('plot_order');
462  foreach ($plot_order as $key => $plot_name) {
463  $dataset = $datasets[$plot_name];
464 
465  $x_axis_name = $dataset['settings']['x_axis'];
466  $y_axis_name = $dataset['settings']['y_axis'];
467  $is_accumulative = intval($dataset['settings']['accumulative']);
468 
469  // dataset processing
470  $data_source_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($dataset['assetid']);
471  $result = $data_source_asset->getResultSet('default');
472 
473  $tmp = 0;
474  $image_dataset = Image_Graph::factory('dataset');
475  foreach ($result as $record) {
476  if ($is_accumulative) {
477  $tmp += intval($record[$y_axis_name]);
478  $image_dataset->addPoint($record[$x_axis_name], $tmp);
479  } else {
480  $image_dataset->addPoint($record[$x_axis_name], intval($record[$y_axis_name]));
481  }
482  }
483 
485  // Plot specific settings //
487  switch ($dataset['settings']['graph_type']) {
488  case 'Image_Graph_Plot_Bar' :
489  case 'Image_Graph_Plot_Area' :
490  // use stacked bar
491  if ($dataset['settings']['use_stacked']) {
492  $multiple_dataset = Array();
493  $multiple_dataset[] = $image_dataset;
494 
495  foreach ($dataset['settings']['stacked_data'] as $stack) {
496  $image_dataset = Image_Graph::factory('dataset');
497  $image_dataset->setName($stack['title']);
498 
499  // add each stack dataset
500  $data_source_asset = $GLOBALS['SQ_SYSTEM']->am->getAsset($stack['datasource']);
501  $result = $data_source_asset->getResultSet('default');
502  foreach ($result as $record) {
503  $image_dataset->addPoint($record[$stack['x_axis']], intval($record[$stack['y_axis']]));
504  }
505  $multiple_dataset[] =$image_dataset;
506 
507  }
508  $plot =& $this->plotarea->addNew($dataset['settings']['graph_type'], Array($multiple_dataset, 'stacked'));
509  } else {
510  $plot =& $this->plotarea->addNew($dataset['settings']['graph_type'], $image_dataset);
511  }
512  break;
513  case 'Image_Graph_Plot_Smoothed_Area' :
514  case 'Image_Graph_Plot_Line' :
515  case 'Image_Graph_Plot_Smoothed_Line' :
516  case 'Image_Graph_Plot_Pie' :
517  case 'Image_Graph_Plot_Step' :
518  case 'Image_Graph_Plot_Impulse' :
519  case 'Image_Graph_Plot_Dot' :
520  case 'Image_Graph_Plot_Radar' :
521  case 'Image_Graph_Plot_CandleStick' :
522  case 'Image_Graph_Plot_Band' :
523  default :
524  $plot =& $this->plotarea->addNew($dataset['settings']['graph_type'], $image_dataset);
525  break;
526 
527  }//end switch
528 
529  if ($dataset['settings']['plot_name'] != $dataset['settings']['display_name']) {
530  $plot->setTitle($dataset['settings']['display_name']);
531  } else {
532  $plot->setTitle($dataset['settings']['plot_name']);
533  }
534 
535  $fill = Image_Graph::factory('Image_Graph_Fill_Array');
536  if ($dataset['settings']['gradient_type'] != 'none') {
537  // gradient colour
538  $grad_type = $this->getGradType($dataset['settings']['gradient_type']);
539  $fill->addNew('gradient', Array($grad_type, '#'.$dataset['settings']['gradient_1'], '#'.$dataset['settings']['gradient_2']));
540  } else {
541  // fill colour
542  $fill->addColor('#'.$dataset['settings']['fill_colour']);
543  }
544 
545  switch ($dataset['settings']['graph_type']) {
546  case 'Image_Graph_Plot_Bar' :
547  $plot->setSpacing(intval($dataset['settings']['bar_spacing']));
548  case 'Image_Graph_Plot_Area' :
549  // use stacked bar
550  if ($dataset['settings']['use_stacked']) {
551  foreach ($dataset['settings']['stacked_data'] as $stack) {
552  if ($stack['gradient_type'] != 'none') {
553  $fill->addNew('gradient', Array($this->getGradType($stack['gradient_type']), '#'.$stack['colour_1'], '#'.$stack['colour_2']));
554  } else {
555  $fill->addColor('#'.$stack['colour_1']);
556  }
557  }
558  }
559  $plot->setFillStyle($fill);
560  $plot->setLineColor('#'.$dataset['settings']['line_colour']);
561  break;
562  case 'Image_Graph_Plot_Line' :
563  case 'Image_Graph_Plot_Smoothed_Area' :
564  case 'Image_Graph_Plot_Smoothed_Line' :
565  case 'Image_Graph_Plot_Pie' :
566  case 'Image_Graph_Plot_Step' :
567  case 'Image_Graph_Plot_Impulse' :
568  case 'Image_Graph_Plot_Dot' :
569  case 'Image_Graph_Plot_Radar' :
570  case 'Image_Graph_Plot_CandleStick' :
571  case 'Image_Graph_Plot_Band' :
572  default :
573  $plot->setFillStyle($fill);
574  $plot->setLineColor('#'.$dataset['settings']['line_colour']);
575  break;
576 
577  }//end switch
578 
579  // marker
580  if (isset($dataset['settings']['marker_type']) && $dataset['settings']['marker_type'] != 'none') {
581  $this->_addMarkerToPlot($dataset, $plot);
582  }
583 
584  }//end foreach
585 
586  if ($to_file) {
587  if (empty($this->_tmp['graph_file_name'])) {
588  // mainly for the dummy file during the asset creation
589  $filename = $this->data_path.'/'.$this->name;
590  $graph->done(Array('filename' => $filename));
591  } else {
592  $graph->done(Array('filename' => $this->_tmp['graph_file_name']));
593  }
594 
595  if ($this->attr('variety_count') > 0) {
596  // Update varieties
597  $GLOBALS['SQ_SYSTEM']->setRunLevel($GLOBALS['SQ_SYSTEM']->getRunLevel() & SQ_RUN_LEVEL_FORCED);
598  $am = $GLOBALS['SQ_SYSTEM']->am;
599  $links = $am->getLinks($this->id, SQ_LINK_TYPE_2, 'image_variety');
600  foreach ($links as $link) {
601  $variety = $am->getAsset($link['minorid'], 'image_variety');
602  if (!$this->saveVariety($variety, TRUE, TRUE, FALSE, FALSE)) {
603  trigger_error('Failed to update the image varieties', E_USER_WARNING);
604  }
605  }
606  $GLOBALS['SQ_SYSTEM']->restoreRunLevel();
607  }
608  } else {
609  $graph->done();
610  }
611 
612  // Restore error level
613  error_reporting($old_err_level);
614 
615  }//end getFinalGraph()
616 
617 
624  function isGraphReady()
625  {
626  $datasets = $this->attr('datasets');
627  $graph_ready = TRUE;
628  foreach ($datasets as $name => $dataset) {
629  if ($dataset['settings']['x_axis'] == 'Not saved' || $dataset['settings']['y_axis'] == 'Not saved') {
630  $graph_ready = FALSE;
631  break;
632  }
633  }
634  return $graph_ready;
635 
636  }//end isGraphReady()
637 
638 
648  function makePlotSettingsPreview($graph_info)
649  {
650  // Turn off error level. PEAR Image package generates
651  // PHP 4 warning, which prevents printFroend() sending
652  // proper header information
653  $old_err_level = error_reporting(0);
654 
655  require_once 'Image/Graph.php';
656  $global_settings = $this->attr('global_settings');
657 
658  $graph =& $this->getNewGraph();
659  $sample_dataset = Image_Graph::factory('random', Array(10, 2, 15, TRUE));
660 
661  // plot settings
662  $plot =& $this->plotarea->addNew($graph_info['settings']['graph_type'], Array(&$sample_dataset));
663  if ($graph_info['settings']['gradient_type'] != 'none') {
664  // gradient colour
665  $grad_type = $this->getGradType($graph_info['settings']['gradient_type']);
666  $fill = Image_Graph::factory('Image_Graph_Fill_Array');
667  $fill->addNew('gradient', Array($grad_type, '#'.$graph_info['settings']['gradient_1'], '#'.$graph_info['settings']['gradient_2']));
668  } else {
669  // fill colour
670  $fill = Image_Graph::factory('Image_Graph_Fill_Array');
671  $fill->addColor('#'.$graph_info['settings']['fill_colour']);
672  }
673  $plot->setFillStyle($fill);
674  $plot->setLineColor('#'.$graph_info['settings']['line_colour']);
675 
677  // Plot specific settings //
679  switch ($graph_info['settings']['graph_type']) {
680  case 'Image_Graph_Plot_Bar' :
681  $plot->setSpacing(intval($graph_info['settings']['bar_spacing']));
682  break;
683  case 'Image_Graph_Plot_Line' :
684  case 'Image_Graph_Plot_Area' :
685  case 'Image_Graph_Plot_Smoothed_Line' :
686  case 'Image_Graph_Plot_Smoothed_Area' :
687  case 'Image_Graph_Plot_Pie' :
688  case 'Image_Graph_Plot_Step' :
689  case 'Image_Graph_Plot_Impulse' :
690  case 'Image_Graph_Plot_Dot' :
691  case 'Image_Graph_Plot_Radar' :
692  case 'Image_Graph_Plot_CandleStick' :
693  case 'Image_Graph_Plot_Band' :
694  break;
695  default :
696  break;
697  }
698 
699  // marker settings
700  if (isset($graph_info['settings']['value_marker']) && $graph_info['settings']['value_marker'] != 'none') {
701  $this->_addMarkerToPlot($graph_info, $plot);
702  }
703 
704  $graph->done();
705 
706  // Restore error level
707  error_reporting($old_err_level);
708 
709  }//end makePlotSettingsPreview()
710 
711 
723  function makeGlobalSettingsPreview($to_file=FALSE)
724  {
725  // Turn off error level. PEAR Image package generates
726  // PHP 4 warning, which prevents printFroend() sending
727  // proper header information
728  $old_err_level = error_reporting(0);
729 
730  $graph = $this->getNewGraph();
731  $sample_dataset = Image_Graph::factory('random', Array(10, 2, 15, TRUE));
732 
733  $plot = $this->plotarea->addNew('Image_Graph_Plot_Bar', Array(&$sample_dataset));
734 
735  if ($to_file) {
736  if (empty($this->_tmp['graph_file_name'])) {
737  // mainly for the dummy file during the asset creation
738  $filename = SQ_DATA_PATH.'/temp/'.strtolower(str_replace(' ', '_', $this->attr('title'))).'.png';
739  $graph->done(Array('filename' => $filename));
740  } else {
741  $graph->done($this->_tmp['graph_file_name']);
742  }
743  } else {
744  $graph->done();
745  }
746 
747  // Restore error level
748  error_reporting($old_err_level);
749 
750  }//end makeGlobalSettingsPreview()
751 
752 
763  function _addMarkerToPlot(&$marker_info, &$plot)
764  {
765  $marker_array = NULL;
766  if ($marker_info['settings']['marker_type'] != 'none') {
767  $marker_type = $marker_info['settings']['marker_type'];
768  $marker_value_type = $marker_info['settings']['value_marker_type'];
769 
770  if ($marker_value_type == 'IMAGE_GRAPH_VALUE_X') {
771  $new_marker =& $plot->addNew($marker_type, IMAGE_GRAPH_VALUE_X);
772  } else if ($marker_value_type == 'IMAGE_GRAPH_VALUE_Y') {
773  $new_marker =& $plot->addNew($marker_type, IMAGE_GRAPH_VALUE_Y);
774  }
775 
776  $new_marker->setFontColor('#'.$marker_info['settings']['marker_font_colour']);
777  $new_marker->setLineColor('#'.$marker_info['settings']['marker_line_colour']);
778  $new_marker->setFillColor('#'.$marker_info['settings']['marker_fill_colour']);
779 
780  $pointing_marker = NULL;
781  if ($marker_info['settings']['pointer_type'] != 'none') {
782  $pointer_type = $marker_info['settings']['pointer_type'];
783  $pointer_length = $marker_info['settings']['pointer_length'];
784  $pointing_marker =& $plot->addNew($pointer_type, Array((int) $pointer_length, &$new_marker));
785  }
786 
787  if (is_null($pointing_marker)) {
788  // set the marker without the pointer
789  $plot->setMarker($new_marker);
790  } else {
791  // set the marker with the pointer
792  $plot->setMarker($pointing_marker);
793  }
794  }
795 
796  }//end _addMarkerToPlot()
797 
798 
799 //-- FRONTEND CACHING --//
800 
801 
810  function printFrontend()
811  {
812  // if we are in limbo, we want to show our editing interface and design
813  // instead of just sending our file over
814  if (SQ_IN_LIMBO) return parent::printFrontend();
815 
816  if (!$this->readAccess()) {
817  $GLOBALS['SQ_SYSTEM']->paintLogin(translate('login'), translate('cannot_access_asset', $this->name));
818  return;
819  }
820 
821  // check the cache. If there is no cache or it's expired,
822  // re-generate the image file
823  $cm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cache_manager');
824  $result = $cm->loadFromCache($this->id, $this->type(), 'default');
825 
826  if ($result === FALSE) $this->updateCache();
827 
828  $existing = $this->getExistingFile();
829  if (!empty($existing)) {
830  require_once SQ_FUDGE_PATH.'/standards_lists/mime_types.inc';
831  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
832 
833  $ext = get_file_type($existing['filename']);
834  $type = (empty($standards_lists_mime_types[$ext])) ? 'text/plain' : $standards_lists_mime_types[$ext];
835  header('Cache-Control:');
836  header('Pragma: cache');
837  header('Expires: '.gmdate('D, d M Y H:i:s', (time() + 86400)).' GMT');
838  header('Content-Type: '.$type);
839  header('Content-Disposition: inline; filename='.$existing['filename'].';');
840  header('Last-Modified: '.gmdate('D, d M Y H:i:s',$existing['modified']).' GMT');
841  header('Content-Length: '.$existing['size']);
842  readfile($existing['path']);
843  @ob_flush();
844  }
845 
846  }//end printFrontend()
847 
848 
860  function updateCache()
861  {
862  $cm = $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('cache_manager');
863 
864  // regenerate the image
865  $this->getFinalGraph(TRUE);
866 
867  // read the file
868  $content = file_get_contents($this->data_path.'/'.$this->name);
869  if ($content === FALSE) {
870  trigger_localised_error('DATA0003', E_USER_WARNING, $this->name);
871  return FALSE;
872  }
873  // cache dummy string, will be used later to check for expiry time of this image file
874  $result = $cm->saveToCache($this->id, $this->type(), 'default', 'Dummy String');
875 
876  return $result;
877 
878  }//end updateCache()
879 
880 
897  function usePublicPath()
898  {
899  return FALSE;
900 
901  }//end usePublicPath()
902 
903 
904 //-- HELPER --//
905 
906 
915  function getGradType($grad_type)
916  {
917  switch ($grad_type) {
918  case 'IMAGE_GRAPH_GRAD_VERTICAL':
919  $grad_type = IMAGE_GRAPH_GRAD_VERTICAL;
920  break;
921  case 'IMAGE_GRAPH_GRAD_HORIZONTAL':
922  $grad_type = IMAGE_GRAPH_GRAD_HORIZONTAL;
923  break;
924  case 'IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED':
925  $grad_type = IMAGE_GRAPH_GRAD_VERTICAL_MIRRORED;
926  break;
927  case 'IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED':
928  $grad_type = IMAGE_GRAPH_GRAD_HORIZONTAL_MIRRORED;
929  break;
930  case 'IMAGE_GRAPH_GRAD_DIAGONALLY_TL_BR':
931  $grad_type = IMAGE_GRAPH_GRAD_DIAGONALLY_TL_BR;
932  break;
933  case 'IMAGE_GRAPH_GRAD_DIAGONALLY_BL_TR':
934  $grad_type = IMAGE_GRAPH_GRAD_DIAGONALLY_BL_TR;
935  break;
936  case 'IMAGE_GRAPH_GRAD_RADIAL':
937  $grad_type = IMAGE_GRAPH_GRAD_RADIAL;
938  break;
939  }
940  return $grad_type;
941 
942  }//end getGradType()
943 
944 
945 //-- NO FILE VERSIONING --//
946 
947 
949  // The below functions are overriden in order to
950  // bypass file versioning functionality in File asset
952 
953 
961  function saveSystemVersion()
962  {
963  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
964 
965  // make sure our data directory exists
966  if (!create_directory($this->data_path)) {
967  trigger_localised_error('CORE0049', E_USER_WARNING, $this->name);
968  return FALSE;
969  }
970 
971  // make sure our system directory exists
972  if (!create_directory($this->data_path.'/.sq_system')) {
973  trigger_localised_error('CORE0050', E_USER_WARNING, $this->name);
974  return FALSE;
975  }
976 
977  // make sure there is nothing in the system directory
978  if (!clear_directory($this->data_path.'/.sq_system')) {
979  trigger_localised_error('CORE0046', E_USER_WARNING, $this->name);
980  return FALSE;
981  }
982 
983  // save the object for later (in the restricted directory)
984  if (!string_to_file(serialize($this), $this->data_path.'/.sq_system/.object_data')) {
985  trigger_localised_error('CORE0051', E_USER_WARNING, $this->name);
986  return FALSE;
987  }
988 
989  // update our lookup tables to not use __data
990  if (!parent::updateLookups()) {
991  trigger_localised_error('CORE0053', E_USER_WARNING, $this->name);
992  return FALSE;
993  }
994 
995  return TRUE;
996 
997  }//end saveSystemVersion()
998 
999 
1007  {
1008  // get the safe edit file name before it's lost
1009  $se_name = $this->attr('name');
1010 
1011  // pretend we are uploading a file because we may be changing the name of the file
1012  // and we want to fool setAttributeValue
1013  $this->_tmp['uploading_file'] = TRUE;
1015  $this->_tmp['uploading_file'] = FALSE;
1016  return FALSE;
1017  }
1018  $this->_tmp['uploading_file'] = FALSE;
1019 
1020  return TRUE;
1021 
1022  }//end revertToSystemVersion()
1023 
1024 
1034  function morph($new_type_code)
1035  {
1036  $am = $GLOBALS['SQ_SYSTEM']->am;
1037 
1038  $file_types = array_merge($am->getTypeAncestors($this->type(), FALSE), $am->getTypeDescendants($this->type()));
1039 
1040  if (in_array($new_type_code, $file_types)) {
1041  // we are morphing into another file type, so check that the actual
1042  // file currently uploaded is not going to conflict with the new type
1043  $am->includeAsset($new_type_code);
1044  $tmp = new $new_type_code();
1045  $existing = $this->getExistingFile();
1046  if (!empty($existing)) {
1047  if (!$tmp->validFile($existing)) {
1048  trigger_localised_error('CORE0008', E_USER_WARNING, $this->name, $new_type_code, $existing['filename'], $new_type_code);
1049  return FALSE;
1050  }
1051 
1052  }
1053  unset($tmp);
1054  }
1055 
1056  return Asset::morph($new_type_code);
1057 
1058  }//end morph()
1059 
1060 
1067  function _checkFileState()
1068  {
1069  if ($this->status & SQ_SC_STATUS_SAFE_EDITING) return TRUE; //don't touch public file in safe edit
1070 
1071  require_once SQ_FUDGE_PATH.'/general/file_system.inc';
1072 
1073  $existing = $this->getExistingFile();
1074  if (empty($existing)) return TRUE;
1075 
1076  $unrestricted = $this->data_path_public.'/'.$existing['filename'];
1077 
1078  $changed = FALSE;
1079 
1080  // if we should be storing our file in the public
1081  // data directory for all the world to see
1082  if ($this->effectiveUnrestricted() && $this->attr('allow_unrestricted')) {
1083  // make sure our data directory exists
1084  if (!create_directory($this->data_path_public)) {
1085  trigger_localised_error('CORE0049', E_USER_WARNING, $this->name);
1086  return FALSE;
1087  }
1088 
1089  if (!file_exists($unrestricted)) {
1090  // copy the file to the public data directory
1091  if (!copy($this->data_path.'/'.$this->name, $unrestricted)) {
1092  trigger_localised_error('DATA0004', E_USER_WARNING, $this->name);
1093  } else {
1094  $changed = TRUE;
1095  }
1096  }
1097  } else {
1098  // need to make sure our file is in the NOT in the public data directory
1099  if (is_file($unrestricted)) {
1100  // unlink the file
1101  if (!unlink($unrestricted)) {
1102  trigger_localised_error('DATA0004', E_USER_WARNING, $this->name);
1103  } else {
1104  $changed = TRUE;
1105  }
1106  }
1107  }//end if effectiveUnrestricted
1108 
1109  if ($changed) {
1110  return $this->updateLookups();
1111  } else {
1112  return TRUE;
1113  }
1114 
1115  }//end _checkFileState()
1116 
1117 
1127  function saveAttributes($dont_run_updated=FALSE)
1128  {
1129  if (!$this->id) return TRUE;
1130 
1131  // if there are no values for the title attribute use the filename
1132  if (trim($this->attr('title')) == '') {
1133  $this->setAttrValue('title', $this->attr('name'));
1134  }//end if
1135 
1136  if (isset($this->_tmp['vars_set']['name'])) {
1137 
1138  $uploading_file = !empty($this->_tmp['uploading_file']);
1139 
1140  if (!$uploading_file) {
1141 
1142  $old_filename = $this->_tmp['vars_set']['name']['old_value'];
1143  $new_filename = $this->attr('name');
1144 
1145  // try and set the new filename - return FALSE if it fails
1146  if (!parent::saveAttributes($dont_run_updated)) {
1147  return FALSE;
1148  }
1149 
1150  if (is_file($this->data_path.'/'.$old_filename)) {
1151  if (!$this->_renameFile($this->data_path, $old_filename, $new_filename)) {
1152  parent::setAttrValue('name', $old_filename);
1153  parent::saveAttributes($dont_run_updated);
1154  return FALSE;
1155  }
1156  }
1157 
1158  if ($this->effectiveUnrestricted()) {
1159  if (is_file($this->data_path_public.'/'.$old_filename)) {
1160  copy($this->data_path_public.'/'.$old_filename, $this->data_path_public.'/'.$new_filename);
1161  unlink($this->data_path_public.'/'.$old_filename);
1162  }
1163  }
1164 
1165  // update the lookups so that the __data path gets rewritten if applicable
1166  $this->updateLookups();
1167 
1168  return TRUE;
1169 
1170  }//end if not uploading a file
1171 
1172  }//end if we are changing the filename
1173 
1174  if (isset($this->_tmp['vars_set']['allow_unrestricted'])) {
1175  // the unrestricted setting is being changed, so we may need to update lookups
1176  if ($this->effectiveUnrestricted() && !($this->status & SQ_SC_STATUS_SAFE_EDITING)) {
1177  $hh = $GLOBALS['SQ_SYSTEM']->getHipoHerder();
1178  $vars = Array('assetids' => Array($this->id));
1179  $hh->queueHipo('hipo_job_update_lookups', $vars);
1180  }
1181  }
1182 
1183  return parent::saveAttributes($dont_run_updated);
1184 
1185  }//end saveAttributes()
1186 
1187 
1198  function _renameFile($data_path, $old_filename, $new_filename)
1199  {
1200  $fv = $GLOBALS['SQ_SYSTEM']->getFileVersioning();
1201 
1202  // copy the file instead of a direct rename because removing the
1203  // file from the repository will also remove it from the file system
1204  if (!copy($data_path.'/'.$old_filename, $data_path.'/'.$new_filename)) {
1205  trigger_localised_error('CORE0026', E_USER_WARNING);
1206  return FALSE;
1207  }
1208 
1209  if (!unlink($data_path.'/'.$old_filename)) {
1210  trigger_localised_error('DATA0004', E_USER_WARNING, $this->name);
1211  return FALSE;
1212  }
1213 
1214  return TRUE;
1215 
1216  }//end _renameFile()
1217 
1218 
1225  function getExistingFile()
1226  {
1227  $info = Array();
1228  $path = $this->data_path.'/'.$this->attr('name');
1229 
1230  if (is_file($path)) {
1231  $info['path'] = $path;
1232  $info['filename'] = basename($info['path']);
1233  $info['modified'] = filemtime($info['path']);
1234  $info['size'] = filesize($info['path']);
1235  }
1236 
1237  if (!empty($info['path'])) {
1238  $size = getimagesize($info['path']);
1239  $info['width'] = $size[0];
1240  $info['height'] = $size[1];
1241  }
1242 
1243  return $info;
1244 
1245  }//end getExistingFile()
1246 
1247 
1248 }//end class
1249 
1250 ?>