1 <?php
  2   3   4   5   6   7   8 
  9 
 10 defined('JPATH_PLATFORM') or die;
 11 
 12  13  14  15  16  17 
 18 class JControllerForm extends JControllerLegacy
 19 {
 20      21  22  23  24  25 
 26     protected $context;
 27 
 28      29  30  31  32  33 
 34     protected $option;
 35 
 36      37  38  39  40  41 
 42     protected $view_item;
 43 
 44      45  46  47  48  49 
 50     protected $view_list;
 51 
 52      53  54  55  56  57 
 58     protected $text_prefix;
 59 
 60      61  62  63  64  65  66  67  68 
 69     public function __construct($config = array())
 70     {
 71         parent::__construct($config);
 72 
 73         
 74         if (empty($this->option))
 75         {
 76             $this->option = 'com_' . strtolower($this->getName());
 77         }
 78 
 79         
 80         if (empty($this->text_prefix))
 81         {
 82             $this->text_prefix = strtoupper($this->option);
 83         }
 84 
 85         
 86         if (empty($this->context))
 87         {
 88             $r = null;
 89 
 90             if (!preg_match('/(.*)Controller(.*)/i', get_class($this), $r))
 91             {
 92                 throw new Exception(JText::_('JLIB_APPLICATION_ERROR_CONTROLLER_GET_NAME'), 500);
 93             }
 94 
 95             $this->context = strtolower($r[2]);
 96         }
 97 
 98         
 99         if (empty($this->view_item))
100         {
101             $this->view_item = $this->context;
102         }
103 
104         
105         if (empty($this->view_list))
106         {
107             
108             
109 
110             
111             
112             $plural = array(
113                 array('/(x|ch|ss|sh)$/i', "$1es"),
114                 array('/([^aeiouy]|qu)y$/i', "$1ies"),
115                 array('/([^aeiouy]|qu)ies$/i', "$1y"),
116                 array('/(bu)s$/i', "$1ses"),
117                 array('/s$/i', 's'),
118                 array('/$/', 's'),
119             );
120 
121             
122             foreach ($plural as $pattern)
123             {
124                 if (preg_match($pattern[0], $this->view_item))
125                 {
126                     $this->view_list = preg_replace($pattern[0], $pattern[1], $this->view_item);
127                     break;
128                 }
129             }
130         }
131 
132         
133         $this->registerTask('apply', 'save');
134         $this->registerTask('save2new', 'save');
135         $this->registerTask('save2copy', 'save');
136     }
137 
138     139 140 141 142 143 144 
145     public function add()
146     {
147         $context = "$this->option.edit.$this->context";
148 
149         
150         if (!$this->allowAdd())
151         {
152             
153             $this->setError(JText::_('JLIB_APPLICATION_ERROR_CREATE_RECORD_NOT_PERMITTED'));
154             $this->setMessage($this->getError(), 'error');
155 
156             $this->setRedirect(
157                 JRoute::_(
158                     'index.php?option=' . $this->option . '&view=' . $this->view_list
159                     . $this->getRedirectToListAppend(), false
160                 )
161             );
162 
163             return false;
164         }
165 
166         
167         JFactory::getApplication()->setUserState($context . '.data', null);
168 
169         
170         $this->setRedirect(
171             JRoute::_(
172                 'index.php?option=' . $this->option . '&view=' . $this->view_item
173                 . $this->getRedirectToItemAppend(), false
174             )
175         );
176 
177         return true;
178     }
179 
180     181 182 183 184 185 186 187 188 189 190 
191     protected function allowAdd($data = array())
192     {
193         $user = JFactory::getUser();
194 
195         return $user->authorise('core.create', $this->option) || count($user->getAuthorisedCategories($this->option, 'core.create'));
196     }
197 
198     199 200 201 202 203 204 205 206 207 208 209 
210     protected function allowEdit($data = array(), $key = 'id')
211     {
212         return JFactory::getUser()->authorise('core.edit', $this->option);
213     }
214 
215     216 217 218 219 220 221 222 223 224 225 226 
227     protected function allowSave($data, $key = 'id')
228     {
229         $recordId = isset($data[$key]) ? $data[$key] : '0';
230 
231         if ($recordId)
232         {
233             return $this->allowEdit($data, $key);
234         }
235         else
236         {
237             return $this->allowAdd($data);
238         }
239     }
240 
241     242 243 244 245 246 247 248 249 
250     public function batch($model)
251     {
252         $vars = $this->input->post->get('batch', array(), 'array');
253         $cid  = $this->input->post->get('cid', array(), 'array');
254 
255         
256         $contexts = array();
257 
258         $option = isset($this->extension) ? $this->extension : $this->option;
259 
260         foreach ($cid as $id)
261         {
262             
263             $contexts[$id] = $option . '.' . $this->context . '.' . $id;
264         }
265 
266         
267         if ($model->batch($vars, $cid, $contexts))
268         {
269             $this->setMessage(JText::_('JLIB_APPLICATION_SUCCESS_BATCH'));
270 
271             return true;
272         }
273         else
274         {
275             $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_FAILED', $model->getError()), 'warning');
276 
277             return false;
278         }
279     }
280 
281     282 283 284 285 286 287 288 289 
290     public function cancel($key = null)
291     {
292         JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
293 
294         $model = $this->getModel();
295         $table = $model->getTable();
296         $context = "$this->option.edit.$this->context";
297 
298         if (empty($key))
299         {
300             $key = $table->getKeyName();
301         }
302 
303         $recordId = $this->input->getInt($key);
304 
305         
306         if ($recordId)
307         {
308             if (property_exists($table, 'checked_out'))
309             {
310                 if ($model->checkin($recordId) === false)
311                 {
312                     
313                     $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()));
314                     $this->setMessage($this->getError(), 'error');
315 
316                     $this->setRedirect(
317                         JRoute::_(
318                             'index.php?option=' . $this->option . '&view=' . $this->view_item
319                             . $this->getRedirectToItemAppend($recordId, $key), false
320                         )
321                     );
322 
323                     return false;
324                 }
325             }
326         }
327 
328         
329         $this->releaseEditId($context, $recordId);
330         JFactory::getApplication()->setUserState($context . '.data', null);
331 
332         $this->setRedirect(
333             JRoute::_(
334                 'index.php?option=' . $this->option . '&view=' . $this->view_list
335                 . $this->getRedirectToListAppend(), false
336             )
337         );
338 
339         return true;
340     }
341 
342     343 344 345 346 347 348 349 350 351 352 
353     public function edit($key = null, $urlVar = null)
354     {
355         
356         JFactory::getApplication()->allowCache(false);
357 
358         $model = $this->getModel();
359         $table = $model->getTable();
360         $cid   = $this->input->post->get('cid', array(), 'array');
361         $context = "$this->option.edit.$this->context";
362 
363         
364         if (empty($key))
365         {
366             $key = $table->getKeyName();
367         }
368 
369         
370         if (empty($urlVar))
371         {
372             $urlVar = $key;
373         }
374 
375         
376         $recordId = (int) (count($cid) ? $cid[0] : $this->input->getInt($urlVar));
377         $checkin = property_exists($table, $table->getColumnAlias('checked_out'));
378 
379         
380         if (!$this->allowEdit(array($key => $recordId), $key))
381         {
382             $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'));
383             $this->setMessage($this->getError(), 'error');
384 
385             $this->setRedirect(
386                 JRoute::_(
387                     'index.php?option=' . $this->option . '&view=' . $this->view_list
388                     . $this->getRedirectToListAppend(), false
389                 )
390             );
391 
392             return false;
393         }
394 
395         
396         if ($checkin && !$model->checkout($recordId))
397         {
398             
399             $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKOUT_FAILED', $model->getError()));
400             $this->setMessage($this->getError(), 'error');
401 
402             $this->setRedirect(
403                 JRoute::_(
404                     'index.php?option=' . $this->option . '&view=' . $this->view_item
405                     . $this->getRedirectToItemAppend($recordId, $urlVar), false
406                 )
407             );
408 
409             return false;
410         }
411         else
412         {
413             
414             $this->holdEditId($context, $recordId);
415             JFactory::getApplication()->setUserState($context . '.data', null);
416 
417             $this->setRedirect(
418                 JRoute::_(
419                     'index.php?option=' . $this->option . '&view=' . $this->view_item
420                     . $this->getRedirectToItemAppend($recordId, $urlVar), false
421                 )
422             );
423 
424             return true;
425         }
426     }
427 
428     429 430 431 432 433 434 435 436 437 438 
439     public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true))
440     {
441         if (empty($name))
442         {
443             $name = $this->context;
444         }
445 
446         return parent::getModel($name, $prefix, $config);
447     }
448 
449     450 451 452 453 454 455 456 457 458 
459     protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id')
460     {
461         $append = '';
462 
463         
464         if ($tmpl = $this->input->get('tmpl', '', 'string'))
465         {
466             $append .= '&tmpl=' . $tmpl;
467         }
468 
469         if ($layout = $this->input->get('layout', 'edit', 'string'))
470         {
471             $append .= '&layout=' . $layout;
472         }
473 
474         if ($forcedLanguage = $this->input->get('forcedLanguage', '', 'cmd'))
475         {
476             $append .= '&forcedLanguage=' . $forcedLanguage;
477         }
478 
479         if ($recordId)
480         {
481             $append .= '&' . $urlVar . '=' . $recordId;
482         }
483 
484         $return = $this->input->get('return', null, 'base64');
485 
486         if ($return)
487         {
488             $append .= '&return=' . $return;
489         }
490 
491         return $append;
492     }
493 
494     495 496 497 498 499 500 
501     protected function getRedirectToListAppend()
502     {
503         $append = '';
504 
505         
506         if ($tmpl = $this->input->get('tmpl', '', 'string'))
507         {
508             $append .= '&tmpl=' . $tmpl;
509         }
510 
511         if ($forcedLanguage = $this->input->get('forcedLanguage', '', 'cmd'))
512         {
513             $append .= '&forcedLanguage=' . $forcedLanguage;
514         }
515 
516         return $append;
517     }
518 
519     520 521 522 523 524 525 526 527 528 529 
530     protected function postSaveHook(JModelLegacy $model, $validData = array())
531     {
532     }
533 
534     535 536 537 538 539 540 
541     public function loadhistory()
542     {
543         $model = $this->getModel();
544         $table = $model->getTable();
545         $historyId = $this->input->getInt('version_id', null);
546 
547         if (!$model->loadhistory($historyId, $table))
548         {
549             $this->setMessage($model->getError(), 'error');
550 
551             $this->setRedirect(
552                 JRoute::_(
553                     'index.php?option=' . $this->option . '&view=' . $this->view_list
554                     . $this->getRedirectToListAppend(), false
555                 )
556             );
557 
558             return false;
559         }
560 
561         
562         if (empty($key))
563         {
564             $key = $table->getKeyName();
565         }
566 
567         $recordId = $table->$key;
568 
569         
570         $urlVar = empty($this->urlVar) ? $key : $this->urlVar;
571 
572         
573         if (!$this->allowEdit(array($key => $recordId), $key))
574         {
575             $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'));
576             $this->setMessage($this->getError(), 'error');
577 
578             $this->setRedirect(
579                 JRoute::_(
580                     'index.php?option=' . $this->option . '&view=' . $this->view_list
581                     . $this->getRedirectToListAppend(), false
582                 )
583             );
584             $table->checkin();
585 
586             return false;
587         }
588 
589         $table->store();
590         $this->setRedirect(
591             JRoute::_(
592                 'index.php?option=' . $this->option . '&view=' . $this->view_item
593                 . $this->getRedirectToItemAppend($recordId, $urlVar), false
594             )
595         );
596 
597         $this->setMessage(
598             JText::sprintf(
599                 'JLIB_APPLICATION_SUCCESS_LOAD_HISTORY', $model->getState('save_date'), $model->getState('version_note')
600             )
601         );
602 
603         
604         $this->postSaveHook($model);
605 
606         return true;
607     }
608 
609     610 611 612 613 614 615 616 617 618 
619     public function save($key = null, $urlVar = null)
620     {
621         
622         JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));
623 
624         $app   = JFactory::getApplication();
625         $model = $this->getModel();
626         $table = $model->getTable();
627         $data  = $this->input->post->get('jform', array(), 'array');
628         $checkin = property_exists($table, $table->getColumnAlias('checked_out'));
629         $context = "$this->option.edit.$this->context";
630         $task = $this->getTask();
631 
632         
633         if (empty($key))
634         {
635             $key = $table->getKeyName();
636         }
637 
638         
639         if (empty($urlVar))
640         {
641             $urlVar = $key;
642         }
643 
644         $recordId = $this->input->getInt($urlVar);
645 
646         
647         $data[$key] = $recordId;
648 
649         
650         if ($task == 'save2copy')
651         {
652             
653             if ($checkin && $model->checkin($data[$key]) === false)
654             {
655                 
656                 $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()));
657                 $this->setMessage($this->getError(), 'error');
658 
659                 $this->setRedirect(
660                     JRoute::_(
661                         'index.php?option=' . $this->option . '&view=' . $this->view_item
662                         . $this->getRedirectToItemAppend($recordId, $urlVar), false
663                     )
664                 );
665 
666                 return false;
667             }
668 
669             
670             $data[$key] = 0;
671             $data['associations'] = array();
672             $task = 'apply';
673         }
674 
675         
676         if (!$this->allowSave($data, $key))
677         {
678             $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'));
679             $this->setMessage($this->getError(), 'error');
680 
681             $this->setRedirect(
682                 JRoute::_(
683                     'index.php?option=' . $this->option . '&view=' . $this->view_list
684                     . $this->getRedirectToListAppend(), false
685                 )
686             );
687 
688             return false;
689         }
690 
691         
692         
693         $form = $model->getForm($data, false);
694 
695         if (!$form)
696         {
697             $app->enqueueMessage($model->getError(), 'error');
698 
699             return false;
700         }
701 
702         
703         $validData = $model->validate($form, $data);
704 
705         
706         if ($validData === false)
707         {
708             
709             $errors = $model->getErrors();
710 
711             
712             for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
713             {
714                 if ($errors[$i] instanceof Exception)
715                 {
716                     $app->enqueueMessage($errors[$i]->getMessage(), 'warning');
717                 }
718                 else
719                 {
720                     $app->enqueueMessage($errors[$i], 'warning');
721                 }
722             }
723 
724             
725             $app->setUserState($context . '.data', $data);
726 
727             
728             $this->setRedirect(
729                 JRoute::_(
730                     'index.php?option=' . $this->option . '&view=' . $this->view_item
731                     . $this->getRedirectToItemAppend($recordId, $urlVar), false
732                 )
733             );
734 
735             return false;
736         }
737 
738         if (!isset($validData['tags']))
739         {
740             $validData['tags'] = null;
741         }
742 
743         
744         if (!$model->save($validData))
745         {
746             
747             $app->setUserState($context . '.data', $validData);
748 
749             
750             $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()));
751             $this->setMessage($this->getError(), 'error');
752 
753             $this->setRedirect(
754                 JRoute::_(
755                     'index.php?option=' . $this->option . '&view=' . $this->view_item
756                     . $this->getRedirectToItemAppend($recordId, $urlVar), false
757                 )
758             );
759 
760             return false;
761         }
762 
763         
764         if ($checkin && $model->checkin($validData[$key]) === false)
765         {
766             
767             $app->setUserState($context . '.data', $validData);
768 
769             
770             $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()));
771             $this->setMessage($this->getError(), 'error');
772 
773             $this->setRedirect(
774                 JRoute::_(
775                     'index.php?option=' . $this->option . '&view=' . $this->view_item
776                     . $this->getRedirectToItemAppend($recordId, $urlVar), false
777                 )
778             );
779 
780             return false;
781         }
782 
783         $langKey = $this->text_prefix . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS';
784         $prefix  = JFactory::getLanguage()->hasKey($langKey) ? $this->text_prefix : 'JLIB_APPLICATION';
785 
786         $this->setMessage(JText::_($prefix . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS'));
787 
788         
789         switch ($task)
790         {
791             case 'apply':
792                 
793                 $recordId = $model->getState($this->context . '.id');
794                 $this->holdEditId($context, $recordId);
795                 $app->setUserState($context . '.data', null);
796                 $model->checkout($recordId);
797 
798                 
799                 $this->setRedirect(
800                     JRoute::_(
801                         'index.php?option=' . $this->option . '&view=' . $this->view_item
802                         . $this->getRedirectToItemAppend($recordId, $urlVar), false
803                     )
804                 );
805                 break;
806 
807             case 'save2new':
808                 
809                 $this->releaseEditId($context, $recordId);
810                 $app->setUserState($context . '.data', null);
811 
812                 
813                 $this->setRedirect(
814                     JRoute::_(
815                         'index.php?option=' . $this->option . '&view=' . $this->view_item
816                         . $this->getRedirectToItemAppend(null, $urlVar), false
817                     )
818                 );
819                 break;
820 
821             default:
822                 
823                 $this->releaseEditId($context, $recordId);
824                 $app->setUserState($context . '.data', null);
825 
826                 $url = 'index.php?option=' . $this->option . '&view=' . $this->view_list
827                     . $this->getRedirectToListAppend();
828 
829                 
830                 $return = $this->input->get('return', null, 'base64');
831 
832                 if (!is_null($return) && JUri::isInternal(base64_decode($return)))
833                 {
834                     $url = base64_decode($return);
835                 }
836 
837                 
838                 $this->setRedirect(JRoute::_($url, false));
839                 break;
840         }
841 
842         
843         $this->postSaveHook($model, $validData);
844 
845         return true;
846     }
847 }
848