Alpha Framework alpha--controller
[ class tree: alpha--controller ] [ index: alpha--controller ] [ all elements ]

Source for file AlphaController.inc

Documentation is available at AlphaController.inc

  1. <?php
  2.  
  3. require_once $config->get('sysRoot').'alpha/util/AlphaErrorHandlers.inc';
  4. require_once $config->get('sysRoot').'alpha/controller/front/FrontController.inc';
  5. require_once $config->get('sysRoot').'alpha/model/types/Date.inc';
  6. require_once $config->get('sysRoot').'alpha/model/types/Timestamp.inc';
  7. require_once $config->get('sysRoot').'alpha/model/types/Double.inc';
  8. require_once $config->get('sysRoot').'alpha/model/types/Integer.inc';
  9. require_once $config->get('sysRoot').'alpha/model/types/String.inc';
  10. require_once $config->get('sysRoot').'alpha/model/types/Text.inc';
  11. require_once $config->get('sysRoot').'alpha/model/types/Enum.inc';
  12. require_once $config->get('sysRoot').'alpha/model/types/Boolean.inc';
  13. require_once $config->get('sysRoot').'alpha/model/PersonObject.inc';
  14. require_once $config->get('sysRoot').'alpha/exceptions/FailedUnitCommitException.inc';
  15. require_once $config->get('sysRoot').'alpha/exceptions/SecurityException.inc';
  16. require_once $config->get('sysRoot').'alpha/exceptions/FileNotFoundException.inc';
  17. require_once $config->get('sysRoot').'alpha/util/helpers/AlphaValidator.inc';
  18.  
  19. /**
  20.  *
  21.  * The master controller class for the Alpha Framework.
  22.  * 
  23.  * @package alpha::controller
  24.  * @since 1.0
  25.  * @author John Collins <dev@alphaframework.org>
  26.  * @version $Id: AlphaController.inc 1453 2011-12-04 15:12:54Z johnc $
  27.  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
  28.  * @copyright Copyright (c) 2011, John Collins (founder of Alpha Framework).
  29.  *  All rights reserved.
  30.  * 
  31.  *  <pre>
  32.  *  Redistribution and use in source and binary forms, with or
  33.  *  without modification, are permitted provided that the
  34.  *  following conditions are met:
  35.  * 
  36.  *  * Redistributions of source code must retain the above
  37.  *    copyright notice, this list of conditions and the
  38.  *    following disclaimer.
  39.  *  * Redistributions in binary form must reproduce the above
  40.  *    copyright notice, this list of conditions and the
  41.  *    following disclaimer in the documentation and/or other
  42.  *    materials provided with the distribution.
  43.  *  * Neither the name of the Alpha Framework nor the names
  44.  *    of its contributors may be used to endorse or promote
  45.  *    products derived from this software without specific
  46.  *    prior written permission.
  47.  *   
  48.  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  49.  *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  50.  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  51.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52.  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  53.  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  54.  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  55.  *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56.  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  57.  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  58.  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  59.  *  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60.  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61.  *  </pre>
  62.  *  
  63.  */
  64. abstract class AlphaController {
  65.     /**
  66.      * The name of the controller
  67.      * 
  68.      * @var string 
  69.      * @since 1.0
  70.      */
  71.     protected $name;
  72.     
  73.     /**
  74.      * Used to set access privileages for the controller to the name of the rights group
  75.      * allowed to access it.  'Public' by default.
  76.      * 
  77.      * @var string 
  78.      * @since 1.0
  79.      */ 
  80.     protected $visibility = 'Public';
  81.     
  82.     /**
  83.      * Optionally, a BO may be set for the default validation form handling code to load in the displayPageHead()
  84.      * method.  The definition of this BO class will need to be included in the child controller.
  85.      * 
  86.      * @var AlphaDAO 
  87.      * @since 1.0
  88.      */
  89.     protected $BO = null;
  90.     
  91.     /**
  92.      * Used to determine if the controller is part of a unit of work sequence
  93.      * (either empty or the name of the unit).
  94.      * 
  95.      * @var string 
  96.      * @since 1.0
  97.      */
  98.     protected $unitOfWork;
  99.     
  100.     /**
  101.      * Stores the start time of a unit of work transaction.
  102.      * 
  103.      * @var Timestamp 
  104.      * @since 1.0
  105.      */
  106.     protected $unitStartTime;
  107.     
  108.     /**
  109.      * Stores the end time of a unit of work transaction.
  110.      * 
  111.      * @var Timestamp. 
  112.      * @since 1.0
  113.      */
  114.     protected $unitEndTime;
  115.     
  116.     /**
  117.      * Stores the maximum allowed time duration (in seconds) of the unit of work.
  118.      * 
  119.      * @var Integer 
  120.      * @since 1.0
  121.      */
  122.     protected $unitMAXDuration;
  123.     
  124.     /**
  125.      * The name of the first controller that is used in this unit of work.
  126.      * 
  127.      * @var string 
  128.      * @since 1.0
  129.      */
  130.     protected $firstJob;
  131.     
  132.     /**
  133.      * The name of the next controller that is used in this unit of work.
  134.      * 
  135.      * @var string 
  136.      * @since 1.0
  137.      */
  138.     protected $nextJob;
  139.     
  140.     /**
  141.      * The name of the previous controller that is used in this unit of work.
  142.      * 
  143.      * @var string 
  144.      * @since 1.0
  145.      */
  146.     protected $previousJob;
  147.     
  148.     /**
  149.      * The name of the last controller that is used in this unit of work.
  150.      * 
  151.      * @var string 
  152.      * @since 1.0
  153.      */
  154.     protected $lastJob;
  155.     
  156.     /**
  157.      * An array for storing dirty objects in a session (i.e. persistent business
  158.      * objects that have not been updated in the database yet).
  159.      * 
  160.      * @var array 
  161.      * @since 1.0
  162.      */
  163.     protected $dirtyObjects = array();
  164.     
  165.     /**
  166.      * An array for storing new objects in a session (transient business objects that
  167.      * have no OID yet).
  168.      * 
  169.      * @var array 
  170.      * @since 1.0
  171.      */
  172.     protected $newObjects = array();
  173.     
  174.     /**
  175.      * The title to be displayed on the controller page
  176.      * 
  177.      * @var string 
  178.      * @since 1.0
  179.      */
  180.     protected $title;
  181.     
  182.     /**
  183.      * Meta keywords for the controller page, generally populated from tags
  184.      * 
  185.      * @var string 
  186.      * @since 1.0
  187.      */
  188.     protected $keywords;
  189.     
  190.     /**
  191.      * Meta description for the controller page.
  192.      * 
  193.      * @var string 
  194.      * @since 1.0
  195.      */
  196.     protected $description;
  197.     
  198.     /**
  199.      * Used to set status update messages to display to the user (messages stored between requests
  200.      * in _SESSION).  Useful for when you want to display a message to a user after POSTing a request,
  201.      * or when moving from one page to the next.
  202.      *
  203.      * @var string 
  204.      * @since 1.0
  205.      */
  206.     protected $statusMessage;
  207.     
  208.     /**
  209.      * Trace logger
  210.      * 
  211.      * @var Logger 
  212.      * @since 1.0
  213.      */
  214.     private static $logger null;
  215.     
  216.     /**
  217.      * Constructor for the AlphaController that starts a new session if required, and handles
  218.      * the population of new/dirty objects from the session when available.  Accepts the name
  219.      * of the rights group that has access to this controller, 'Public' by default.
  220.      * 
  221.      * @param string $visibility The name of the rights group that can access this controller.
  222.      * @since 1.0
  223.      */
  224.     public function __construct($visibility='Public'{
  225.         self::$logger new Logger('AlphaController');
  226.         self::$logger->debug('>>__construct(visibility=['.$visibility.'])');
  227.         
  228.          global $config;
  229.          
  230.          // kick off new session, or reuse existing one
  231.          if(!isset($_SESSION))
  232.              session_start();
  233.          
  234.          // set the access rights to the group name indicated
  235.          $this->visibility = $visibility;
  236.          
  237.          // check the current user's rights on access to the page controller
  238.          if(!$this->checkRights()) {
  239.              $this->accessError();
  240.              // no more execution should take place
  241.              exit;
  242.          }
  243.          
  244.          // if configured to do so, force redirect to the front controller
  245.          if($config->get('sysForceFC'&& basename($_SERVER['PHP_SELF']!= 'index.php'{
  246.              // set the correct HTTP header for the response
  247.                 header('HTTP/1.1 301 Moved Permanently');
  248.             
  249.                 if(empty($_SERVER['QUERY_STRING'])) {
  250.                     header('Location: '.$config->get('sysURL').'?act='.get_class($this));
  251.                     self::$logger->debug('<<__construct');
  252.                     exit;
  253.                 }else{
  254.                     header('Location: '.$config->get('sysURL').'?act='.get_class($this).'&'.$_SERVER['QUERY_STRING']);
  255.                     self::$logger->debug('<<__construct');
  256.                     exit;
  257.                 }
  258.  
  259.                 // we're done here
  260.                 self::$logger->debug('<<__construct');
  261.                 return;
  262.          }
  263.          
  264.          $this->unitStartTime = new Timestamp(date("Y-m-d H:i:s"));
  265.          $this->unitEndTime = new Timestamp();
  266.          $this->unitMAXDuration = new Integer();
  267.          
  268.          // uses controller class name as the job name
  269.         if($this->name == '')
  270.              $this->setName(get_class($this));
  271.          
  272.          if(isset($_SESSION['unitOfWork']&& is_array($_SESSION['unitOfWork']))
  273.              $this->setUnitOfWork($_SESSION['unitOfWork']);
  274.          
  275.          if(isset($_SESSION['dirtyObjects']&& is_array($_SESSION['dirtyObjects']))
  276.              $this->dirtyObjects = $_SESSION['dirtyObjects'];
  277.          
  278.          if(isset($_SESSION['newObjects']&& is_array($_SESSION['newObjects']))
  279.              $this->newObjects = $_SESSION['newObjects'];
  280.          
  281.          if(isset($_SESSION['statusMessage']))
  282.              $this->setStatusMessage($_SESSION['statusMessage']);
  283.  
  284.          self::$logger->debug('<<__construct');
  285.      }
  286.      
  287.      /**
  288.       * Get the BO for this controller (if any).
  289.       * 
  290.       * @return mixed 
  291.        * @since 1.0
  292.       */
  293.      public function getBO({
  294.          self::$logger->debug('>>getBO()');
  295.          self::$logger->debug('<<getBO ['.var_export($this->BOtrue).']');
  296.          return $this->BO;
  297.      }
  298.      
  299.      /**
  300.       * Setter for the BO for this controller.
  301.       * 
  302.       * @param AlphaDAO $BO 
  303.        * @since 1.0
  304.       */ 
  305.      public function setBO($BO{
  306.          self::$logger->debug('>>setBO(BO=['.var_export($BOtrue).'])');
  307.          $this->BO = $BO;
  308.          
  309.          // if the BO has tags, use these as the meta keywords for this controller
  310.          if($this->BO->isTagged()) {
  311.              $tags $this->BO->getPropObject('tags')->getRelatedObjects();
  312.              
  313.              $keywords '';
  314.             
  315.             if(count($tags0{
  316.                 foreach($tags as $tag)
  317.                     $keywords .= ','.$tag->get('content');
  318.             }
  319.             
  320.             $this->setKeywords(substr($keywords1));
  321.          }
  322.          
  323.          self::$logger->debug('<<setBO');
  324.      }
  325.      
  326.      /**
  327.       * Get the name of the unit of work job.
  328.       * 
  329.       * @return string 
  330.        * @since 1.0
  331.       */
  332.      public function getName({
  333.          self::$logger->debug('>>getName()');
  334.          self::$logger->debug('<<getName ['.$this->name.']');
  335.          return $this->name;
  336.      }
  337.      
  338.      /**
  339.       * Setter for the unit of work job name.
  340.       * 
  341.       * @param string $name 
  342.        * @since 1.0
  343.       */ 
  344.      public function setName($name{            
  345.          self::$logger->debug('>>setName(name=['.$name.'])');
  346.          $this->name = $name;
  347.          self::$logger->debug('<<setName');
  348.      }
  349.      
  350.      /**
  351.       * Get the name of the rights group that has access to this controller.
  352.       * 
  353.       * @return string 
  354.        * @since 1.0
  355.       */
  356.      public function getVisibility({
  357.          self::$logger->debug('>>getVisibility()');
  358.          self::$logger->debug('<<getVisibility ['.$this->visibility.']');
  359.          return $this->visibility;
  360.      }
  361.      
  362.      /**
  363.       * Setter for the name of the rights group that has access to this controller.
  364.       * 
  365.       * @param string $visibility 
  366.        * @since 1.0
  367.       */
  368.      public function setVisibility($visibility{
  369.          self::$logger->debug('>>setVisibility(visibility=['.$visibility.'])');
  370.          $this->visibility = $visibility;
  371.          self::$logger->debug('<<setVisibility');
  372.      }
  373.      
  374.      /**
  375.       * Gets the name of the first job in this unit of work.
  376.       * 
  377.       * @return string 
  378.        * @since 1.0
  379.       */
  380.      public function getFirstJob({
  381.          self::$logger->debug('>>getFirstJob()');
  382.          self::$logger->debug('<<getFirstJob ['.$this->firstJob.']');
  383.          return $this->firstJob;
  384.      }
  385.      
  386.      /**
  387.       * Gets the name of the next job in this unit of work
  388.       * 
  389.       * @return string 
  390.        * @since 1.0
  391.       */
  392.      public function getNextJob({
  393.          self::$logger->debug('>>getNextJob()');
  394.          self::$logger->debug('<<getNextJob ['.$this->nextJob.']');
  395.          return $this->nextJob;
  396.      }
  397.      
  398.      /**
  399.       * Gets the name of the previous job in this unit of work
  400.       * 
  401.       * @return string 
  402.        * @since 1.0
  403.       */
  404.      public function getPreviousJob({
  405.          self::$logger->debug('>>getPreviousJob()');
  406.          self::$logger->debug('<<getPreviousJob ['.$this->previousJob.']');
  407.          return $this->previousJob;
  408.      }
  409.      
  410.      /**
  411.       * Gets the name of the last job in this unit of work.
  412.       * 
  413.       * @return string 
  414.        * @since 1.0
  415.       */
  416.      public function getLastJob({
  417.          self::$logger->debug('>>getLastJob()');
  418.          self::$logger->debug('<<getLastJob ['.$this->lastJob.']');
  419.          return $this->lastJob;
  420.      }
  421.      
  422.      /**
  423.       * Sets the name of the controller job sequence to the values in the supplied
  424.       * array (and stores the array in the session).
  425.       * 
  426.       * @param array $jobs The names of the controllers in this unit of work sequence.
  427.       * @throws IllegalArguementException
  428.        * @since 1.0
  429.       */
  430.      public function setUnitOfWork($jobs{
  431.          self::$logger->debug('>>setUnitOfWork(jobs=['.var_export($jobstrue).'])');
  432.          
  433.          if(method_exists($this'before_setUnitOfWork_callback'))
  434.             $this->before_setUnitOfWork_callback();
  435.             
  436.          if(!is_array($jobs)) {
  437.             throw new IllegalArguementException('Bad $jobs array ['.var_export($jobstrue).'] passed to setUnitOfWork method!');
  438.             self::$logger->debug('<<setUnitOfWork');
  439.             return;
  440.         }
  441.  
  442.         // validate that each controller name in the array actually exists
  443.         foreach($jobs as $job{
  444.             if(!AlphaController::checkControllerDefExists($job))
  445.                 throw new IllegalArguementException('The controller name ['.$job.'] provided in the jobs array is not defined anywhere!');
  446.         }
  447.  
  448.         // clear out any previous unit of work from the session
  449.         $_SESSION['unitOfWork'null;        
  450.         $this->dirtyObjects = array();
  451.         $this->newObjects = array();
  452.         
  453.          $numOfJobs count($jobs);
  454.          
  455.          for($i=0$i<$numOfJobs$i++{
  456.              // the first job in the sequence
  457.              if($i==0{
  458.                  $this->firstJob = $jobs[$i];
  459.                  self::$logger->debug('First job ['.$this->firstJob.']');
  460.              }
  461.              // found the current job
  462.              if($this->name == $jobs[$i]{
  463.                  if(isset($jobs[$i-1])) {
  464.                      // set the previous job if it exists
  465.                      $this->previousJob = $jobs[$i-1];
  466.                      self::$logger->debug('Previous job ['.$this->previousJob.']');
  467.                  }
  468.                  if(isset($jobs[$i+1])) {
  469.                      // set the next job if it exists
  470.                      $this->nextJob = $jobs[$i+1];
  471.                      self::$logger->debug('Next job ['.$this->nextJob.']');
  472.                  }
  473.              }
  474.              // the last job in the sequence
  475.              if($i==($numOfJobs-1)) {
  476.                  $this->lastJob = $jobs[$i];
  477.              }    
  478.          }
  479.          
  480.          $_SESSION['unitOfWork'$jobs;
  481.          
  482.          if(method_exists($this'after_setUnitOfWork_callback'))
  483.             $this->after_setUnitOfWork_callback();
  484.             
  485.         self::$logger->debug('<<setUnitOfWork');
  486.      }
  487.      
  488.      /**
  489.       * Getter for the unit start time.
  490.       * 
  491.       * @return Timestamp 
  492.        * @since 1.0
  493.       */
  494.      public function getStartTime({
  495.          self::$logger->debug('>>getStartTime()');
  496.          self::$logger->debug('<<getStartTime ['.$this->unitStartTime.']');
  497.          return $this->unitStartTime;
  498.      }
  499.      
  500.      /**
  501.       * Setter for the unit start time (value will be stored in the session as key unitStartTime).
  502.       * 
  503.       * @param integer $year 
  504.       * @param integer $month 
  505.       * @param integer $day 
  506.       * @param integer $hour 
  507.       * @param integer $minute 
  508.       * @param integer $second 
  509.        * @since 1.0
  510.       */
  511.      public function setUnitStartTime($year$month$day$hour$minute$second{
  512.          self::$logger->debug('>>setUnitStartTime(year=['.$year.'], month=['.$month.'], day=['.$day.'], hour=['.$hour.'], minute=['.$minute.'],
  513.              second=['.$second.'])');
  514.          
  515.          $this->unitStartTime->setTimestampValue($year$month$day$hour$minute$second);
  516.          $_SESSION['unitStartTime'$this->unitStartTime->getValue();
  517.          
  518.          self::$logger->debug('<<setUnitStartTime');
  519.      }
  520.      
  521.      /**
  522.       * Getter for the unit end time.
  523.       * 
  524.       * @return Timestamp 
  525.        * @since 1.0
  526.       */
  527.      public function getEndTime({
  528.          self::$logger->debug('>>getEndTime()');
  529.          self::$logger->debug('<<getEndTime ['.$this->unitEndTime.']');
  530.          return $this->unitEndTime;
  531.      }
  532.      
  533.      /**
  534.       * Setter for the unit end time (value will be stored in the session as key unitEndTime).
  535.       * 
  536.       * @param integer $year 
  537.       * @param integer $month 
  538.       * @param integer $day 
  539.       * @param integer $hour 
  540.       * @param integer $minute 
  541.       * @param integer $second 
  542.        * @since 1.0
  543.       */
  544.      public function setUnitEndTime($year$month$day$hour$minute$second{
  545.          self::$logger->debug('>>setUnitEndTime(year=['.$year.'], month=['.$month.'], day=['.$day.'], hour=['.$hour.'], minute=['.$minute.'],
  546.           second=['.$second.'])');
  547.          
  548.          $this->unitEndTime->setTimestampValue($year$month$day$hour$minute$second);
  549.          $_SESSION['unitEndTime'$this->unitEndTime->getValue();
  550.          
  551.          self::$logger->debug('<<setUnitEndTime');
  552.      }
  553.      
  554.      /**
  555.       * Getter for the unit of work MAX duration.
  556.       * 
  557.       * @return Integer 
  558.        * @since 1.0
  559.       */
  560.      public function getMAXDuration({
  561.          self::$logger->debug('>>getMAXDuration()');
  562.          self::$logger->debug('<<getMAXDuration ['.$this->unitMAXDuration.']');
  563.          return $this->unitMAXDuration;
  564.      }
  565.      
  566.      /**
  567.       * Setter for the unit MAX duration.
  568.       * 
  569.       * @param integer $duration The desired duration in seconds.
  570.        * @since 1.0
  571.       */
  572.      public function setUnitMAXDuration($duration{
  573.          self::$logger->debug('>>setUnitMAXDuration(duration=['.$duration.'])');
  574.          $this->unitMAXDuration->setValue($duration);
  575.          self::$logger->debug('<<setUnitMAXDuration');
  576.      }
  577.      
  578.      /**
  579.       * Calculates and returns the unit of work current duration in seconds.
  580.       * 
  581.       * @return integer 
  582.        * @since 1.0
  583.       */
  584.      public function getUnitDuration({
  585.          self::$logger->debug('>>getUnitDuration()');
  586.          
  587.          $intStartTime mktime(
  588.              $this->unitStartTime->getHour(),
  589.              $this->unitStartTime->getMinute(),
  590.              $this->unitStartTime->getSecond(),
  591.              $this->unitStartTime->getMonth(),
  592.              $this->unitStartTime->getDay(),
  593.              $this->unitStartTime->getYear()
  594.              );
  595.          
  596.          $intEndTime mktime(
  597.              $this->unitEndTime->getHour(),
  598.              $this->unitEndTime->getMinute(),
  599.              $this->unitEndTime->getSecond(),
  600.              $this->unitEndTime->getMonth(),
  601.              $this->unitEndTime->getDay(),
  602.              $this->unitEndTime->getYear()
  603.              );
  604.          
  605.          self::$logger->debug('<<getUnitDuration ['.$intEndTime-$intStartTime.']');
  606.          return $intEndTime-$intStartTime;
  607.      }
  608.      
  609.      /**
  610.       * Adds the supplied business object to the dirtyObjects array in the session.
  611.       * 
  612.       * @param AlphaDAO $object 
  613.        * @since 1.0
  614.       */
  615.      public function markDirty($object{
  616.          self::$logger->debug('>>markDirty(object=['.var_export($objecttrue).'])');
  617.          
  618.          if(method_exists($this'before_markDirty_callback'))
  619.             $this->before_markDirty_callback();
  620.         
  621.          $this->dirtyObjects[count($this->dirtyObjects)$object;
  622.          
  623.          $_SESSION['dirtyObjects'$this->dirtyObjects;
  624.          
  625.          if(method_exists($this'after_markDirty_callback'))
  626.             $this->after_markDirty_callback();
  627.         
  628.         self::$logger->debug('<<markDirty');
  629.      }
  630.      
  631.      /**
  632.       * Getter for the dirty objects array.
  633.       * 
  634.       * @return array 
  635.        * @since 1.0
  636.       */
  637.      public function getDirtyObjects({
  638.          self::$logger->debug('>>getDirtyObjects()');
  639.          self::$logger->debug('<<getDirtyObjects ['.var_export($this->dirtyObjectstrue).']');
  640.          return $this->dirtyObjects;
  641.      }
  642.      
  643.      /**
  644.       * Adds a newly created business object to the newObjects array in the session.
  645.       * 
  646.       * @param AlphaDAO $object 
  647.        * @since 1.0
  648.       */
  649.      public function markNew($object{
  650.          self::$logger->debug('>>markNew(object=['.var_export($objecttrue).'])');
  651.          
  652.          if(method_exists($this'before_markNew_callback'))
  653.             $this->before_markNew_callback();
  654.         
  655.          $this->newObjects[count($this->newObjects)$object;
  656.          
  657.          $_SESSION['newObjects'$this->newObjects;
  658.          
  659.          if(method_exists($this'after_markNew_callback'))
  660.             $this->after_markNew_callback();
  661.             
  662.         self::$logger->debug('<<markNew');
  663.      }
  664.      
  665.      /**
  666.       * Getter for the new objects array.
  667.       * 
  668.       * @return array 
  669.        * @since 1.0
  670.       */
  671.      public function getNewObjects({
  672.          self::$logger->debug('>>getNewObjects()');
  673.          self::$logger->debug('<<getNewObjects ['.var_export($this->newObjectstrue).']');
  674.          return $this->newObjects;
  675.      }
  676.      
  677.     /**
  678.      * Commits (saves) all of the new and modified (dirty) objects in the unit of work to the database.
  679.      *
  680.      * @throws FailedUnitCommitException
  681.       * @since 1.0
  682.      */
  683.     public function commit({
  684.         self::$logger->debug('>>commit()');
  685.         
  686.         if(method_exists($this'before_commit_callback'))
  687.             $this->before_commit_callback();
  688.         
  689.         AlphaDAO::begin();
  690.  
  691.         $newObjects $this->getNewObjects();
  692.         
  693.         $count count($newObjects);
  694.  
  695.         for ($i 0$i $count$i++{
  696.             try {
  697.                 $newObjects[$i]->save();
  698.             }catch (FailedSaveException $e{
  699.                 throw new FailedUnitCommitException($e->getMessage());
  700.                 self::$logger->error('Failed to save new object of type ['.get_class($newObjects[$i]).'], aborting...');
  701.                 $this->abort();
  702.                 return;
  703.             }catch (LockingException $e{
  704.                 throw new FailedUnitCommitException($e->getMessage());
  705.                 self::$logger->error('Failed to save new object of type ['.get_class($newObjects[$i]).'], aborting...');
  706.                 $this->abort();
  707.                 return;
  708.             }
  709.         }
  710.         
  711.         $dirtyObjects $this->getDirtyObjects();
  712.         
  713.         $count count($dirtyObjects);
  714.  
  715.         for ($i 0$i $count$i++{
  716.             try {
  717.                 $dirtyObjects[$i]->save();
  718.             }catch (FailedSaveException $e{
  719.                 throw new FailedUnitCommitException($e->getMessage());
  720.                 self::$logger->error('Failed to save OID ['.$dirtyObjects[$i]->getID().'] of type ['.get_class($dirtyObjects[$i]).'], aborting...');
  721.                 $this->abort();
  722.                 return;
  723.             }catch (LockingException $e{
  724.                 throw new FailedUnitCommitException($e->getMessage());
  725.                 self::$logger->error('Failed to save OID ['.$dirtyObjects[$i]->getID().'] of type ['.get_class($dirtyObjects[$i]).'], aborting...');
  726.                 $this->abort();
  727.                 return;
  728.             }
  729.         }
  730.  
  731.         try{
  732.             AlphaDAO::commit();
  733.             
  734.             $this->clearUnitOfWorkAttributes();
  735.         
  736.             if(method_exists($this'after_commit_callback'))
  737.                 $this->after_commit_callback();
  738.             
  739.             self::$logger->debug('<<commit');
  740.         }catch(FailedSaveException $e{
  741.             throw new FailedUnitCommitException('Failed to commit the transaction, error is ['.$e->getMessage().']');
  742.             self::$logger->debug('<<commit');
  743.         }        
  744.     }
  745.     
  746.     /**
  747.      * Method to clearup a cancelled unit of work.
  748.      *
  749.      * @throws AlphaException
  750.      * @since 1.0
  751.      */
  752.     public function abort({
  753.         self::$logger->debug('>>abort()');
  754.         
  755.         if(method_exists($this'before_abort_callback'))
  756.             $this->before_abort_callback();
  757.  
  758.         try{
  759.             AlphaDAO::rollback();
  760.             
  761.             $this->clearUnitOfWorkAttributes();
  762.         
  763.             if(method_exists($this'after_abort_callback'))
  764.                 $this->after_abort_callback();
  765.             
  766.             self::$logger->debug('<<abort');
  767.         }catch(AlphaException $e{
  768.             throw new AlphaException('Failed to rollback the transaction, error is ['.$e->getMessage().']');
  769.             self::$logger->debug('<<abort');
  770.         }        
  771.     }
  772.     
  773.     /**
  774.      * Clears the session and object attributes related to unit of work sessions
  775.      */
  776.     private function clearUnitOfWorkAttributes({
  777.         $_SESSION['unitOfWork'null;
  778.         $this->unitOfWork = null;
  779.         $_SESSION['dirtyObjects'null;
  780.         $this->dirtyObjects = array();
  781.         $_SESSION['newObjects'null;
  782.         $this->newObjects = array();
  783.     }
  784.     
  785.     /**
  786.      * Getter for the page title.
  787.      * 
  788.      * @return string 
  789.      * @since 1.0
  790.      */
  791.     public function getTitle({
  792.         self::$logger->debug('>>getTitle()');
  793.         self::$logger->debug('<<getTitle ['.$this->title.']');
  794.         return $this->title;    
  795.     }
  796.     
  797.     /**
  798.      * Setter for the page title.
  799.      * 
  800.      * @param string $title 
  801.      * @since 1.0
  802.      */
  803.     public function setTitle($title{
  804.         self::$logger->debug('>>setTitle(title=['.$title.'])');
  805.         self::$logger->debug('<<setTitle');
  806.         $this->title = $title;    
  807.     }
  808.     
  809.     /**
  810.      * Getter for the page description.
  811.      * 
  812.      * @return string 
  813.      * @since 1.0
  814.      */
  815.     public function getDescription({
  816.         self::$logger->debug('>>getDescription()');
  817.         self::$logger->debug('<<getDescription ['.$this->description.']');
  818.         return $this->description;    
  819.     }
  820.     
  821.     /**
  822.      * Setter for the page description.
  823.      * 
  824.      * @param string $description 
  825.      * @since 1.0
  826.      */
  827.     public function setDescription($description{
  828.         self::$logger->debug('>>setDescription(description=['.$description.'])');
  829.         self::$logger->debug('<<setDescription');
  830.         $this->description = $description;    
  831.     }
  832.     
  833.     /**
  834.      * Getter for the page keywords.
  835.      * 
  836.      * @return string 
  837.      * @since 1.0
  838.      */
  839.     public function getKeywords({
  840.         self::$logger->debug('>>getKeywords()');
  841.         self::$logger->debug('<<getKeywords ['.$this->keywords.']');
  842.         return $this->keywords;    
  843.     }
  844.     
  845.     /**
  846.      * Setter for the page keywords, should pass a comma-seperated list as a string.
  847.      * 
  848.      * @param string $keywords 
  849.      * @since 1.0
  850.      */
  851.     public function setKeywords($keywords{
  852.         self::$logger->debug('>>setKeywords(keywords=['.$keywords.'])');
  853.         self::$logger->debug('<<setKeywords');
  854.         $this->keywords = $keywords;
  855.     }
  856.     
  857.     /**
  858.      * Method to display an access error for trespassing users.  HTTP response header code will be 403.
  859.      * 
  860.      * @since 1.0
  861.      */
  862.     public function accessError({
  863.         self::$logger->debug('>>accessError()');
  864.         
  865.         if(method_exists($this'before_accessError_callback'))
  866.             $this->before_accessError_callback();
  867.         
  868.         global $config;        
  869.         
  870.         if(isset($_SESSION['currentUser']))
  871.             self::$logger->warn('The user ['.$_SESSION['currentUser']->get('email').'] attempted to access the resource ['.$_SERVER['REQUEST_URI'].'] but was denied due to insufficient rights');
  872.         else
  873.             self::$logger->warn('An unknown user attempted to access the resource ['.$_SERVER['REQUEST_URI'].'] but was denied due to insufficient rights');
  874.             
  875.         header('HTTP/1.1 403 Forbidden');
  876.         $front new FrontController();
  877.         echo AlphaView::renderErrorPage(403'You do not have the correct access rights to view this page.  If you have not logged in yet, try going back to the home page and logging in from there.');
  878.         
  879.         if(method_exists($this'after_accessError_callback'))
  880.             $this->after_accessError_callback();
  881.         
  882.         self::$logger->debug('<<accessError');
  883.     }
  884.     
  885.     /**
  886.      * Checks the user rights of the currently logged-in person against the page
  887.      * visibility set for this controller.  Will return false if the user has
  888.      * not got the correct rights.
  889.      * 
  890.      * @return boolean 
  891.      * @since 1.0
  892.      */
  893.     public function checkRights({
  894.         self::$logger->debug('>>checkRights()');
  895.         
  896.         if(method_exists($this'before_checkRights_callback'))
  897.             $this->before_checkRights_callback();
  898.         
  899.         // firstly if the page is Public then there is no issue
  900.         if ($this->getVisibility(== 'Public'{
  901.             if(method_exists($this'after_checkRights_callback'))
  902.                 $this->after_checkRights_callback();
  903.             
  904.             self::$logger->debug('<<checkRights [true]');
  905.             return true;
  906.         }else{
  907.             // the person is logged in?
  908.             if (isset($_SESSION['currentUser'])) {
  909.                 // checking for admins (can access everything)                
  910.                 if ($_SESSION['currentUser']->inGroup('Admin')) {
  911.                     if(method_exists($this'after_checkRights_callback'))
  912.                         $this->after_checkRights_callback();
  913.                     
  914.                     self::$logger->debug('<<checkRights [true]');
  915.                     return true;
  916.                 elseif ($_SESSION['currentUser']->inGroup($this->getVisibility())) {
  917.                     if(method_exists($this'after_checkRights_callback'))
  918.                         $this->after_checkRights_callback();
  919.                     
  920.                     self::$logger->debug('<<checkRights [true]');
  921.                     return true;
  922.                 // the person is editing their own profile which is allowed
  923.                 elseif (get_class($this->BO== 'PersonObject' && $_SESSION['currentUser']->getDisplayName(== $this->BO->getDisplayName()) {
  924.                     if(method_exists($this'after_checkRights_callback'))
  925.                         $this->after_checkRights_callback();
  926.                     
  927.                     self::$logger->debug('<<checkRights [true]');
  928.                     return true;
  929.                 }else{
  930.                     self::$logger->debug('<<checkRights [false]');
  931.                     return false;
  932.                 }
  933.             }else// the person is NOT logged in
  934.                 self::$logger->debug('<<checkRights [false]');
  935.                 return false;
  936.             }
  937.         }
  938.     }
  939.     
  940.     /**
  941.      * Method to check the validity of the two hidden form security
  942.      * fields which aim to ensure that a post to the controller is being sent from
  943.      * the same server that is hosting it.
  944.      * 
  945.      * @return boolean 
  946.      * @since 1.0
  947.      */
  948.     public static function checkSecurityFields({
  949.         if(self::$logger == null)
  950.             self::$logger new Logger('AlphaController');
  951.         self::$logger->debug('>>checkSecurityFields()');
  952.         
  953.         // the server hostname + today's date
  954.         $var1 md5($_SERVER['HTTP_HOST'].date("Ymd"));
  955.         // the server's IP plus $var1
  956.         $var2 md5($_SERVER['REMOTE_ADDR'].$var1);
  957.         
  958.         if(empty($_REQUEST['var1']|| empty($_REQUEST['var2'])) {
  959.             self::$logger->warn('The required var1/var2 params where not provided on the HTTP request');
  960.             self::$logger->debug('<<checkSecurityFields [false]');
  961.             return false;
  962.         }
  963.         
  964.         if ($var1 == $_REQUEST['var1'&& $var2 == $_REQUEST['var2']{            
  965.             self::$logger->debug('<<checkSecurityFields [true]');
  966.             return true;
  967.         }else{
  968.             /*
  969.              * Here we are implementing a "grace period" of one hour if the time is < 1:00AM, we will accept
  970.              * a match for yesterday's date in the security fields
  971.              * 
  972.              */            
  973.             
  974.             // the server hostname + today's date less 1 hour (i.e. yesterday where time is < 1:00AM)
  975.             $var1 md5($_SERVER['HTTP_HOST'].date("Ymd"(time()-3600)));
  976.             // the server's IP plus $var1
  977.             $var2 md5($_SERVER['REMOTE_ADDR'].$var1);
  978.             
  979.             if ($var1 == $_REQUEST['var1'&& $var2 == $_REQUEST['var2']{                
  980.                 self::$logger->debug('<<checkSecurityFields [true]');
  981.                 return true;
  982.             }else{
  983.                 self::$logger->warn('The var1/var2 params provided are invalid, values: var1=['.$_REQUEST['var1'].'] var2=['.$_REQUEST['var2'].']');
  984.                 self::$logger->debug('<<checkSecurityFields [false]');
  985.                 return false;
  986.             }
  987.         }
  988.     }
  989.     
  990.     /**
  991.      * Generates the two security fields to prevent remote form processing.
  992.      * 
  993.      * @return array An array containing the two fields
  994.      * @since 1.0
  995.      */
  996.     public static function generateSecurityFields({
  997.         if(self::$logger == null)
  998.             self::$logger new Logger('AlphaController');
  999.         self::$logger->debug('>>generateSecurityFields()');
  1000.         
  1001.         // the server hostname + today's date
  1002.         $var1 md5($_SERVER['HTTP_HOST'].date("Ymd"));
  1003.         // the server's IP plus $var1
  1004.         $var2 md5($_SERVER['REMOTE_ADDR'].$var1);
  1005.         
  1006.         self::$logger->debug('<<generateSecurityFields [array('.$var1.', '.$var2.')]');
  1007.         return array($var1$var2);
  1008.     }
  1009.     
  1010.     /**
  1011.      * Returns the name of a custom controller if one is found, otherwise returns null.
  1012.      *
  1013.      * @param string $BOName The classname of the business object
  1014.      * @param string $mode The mode of the controller (create, view, edit)
  1015.      * @return string 
  1016.      * @since 1.0
  1017.      */
  1018.     public static function getCustomControllerName($BOName$mode{
  1019.         if(self::$logger == null)
  1020.             self::$logger new Logger('AlphaController');
  1021.         self::$logger->debug('>>getCustomControllerName(BOName=['.$BOName.'], mode=['.$mode.'])');
  1022.         
  1023.         global $config;
  1024.         
  1025.         // strip the Object part from the class name
  1026.         $BOName substr($BOName0strpos($BOName'Object'));
  1027.         // uppercase the first letter of each word, e.g. create cart becomes Create Cart
  1028.         $controllerName ucwords($mode.' '.$BOName);
  1029.         // remove spaces
  1030.         $controllerName str_replace(' '''$controllerName);
  1031.  
  1032.         self::$logger->debug('Custom controller name is ['.$controllerName.']');
  1033.         
  1034.         if (file_exists($config->get('sysRoot').'controller/'.$controllerName.'.php')) {
  1035.             self::$logger->debug('<<getCustomControllerName');
  1036.             return $controllerName;
  1037.         }elseif (file_exists($config->get('sysRoot').'alpha/controller/'.$controllerName.'.php')) {
  1038.             self::$logger->debug('<<getCustomControllerName');
  1039.             return $controllerName;
  1040.         }else{
  1041.             self::$logger->debug('<<getCustomControllerName');
  1042.             return null;
  1043.         }        
  1044.     }
  1045.     
  1046.     /**
  1047.      * Does a HTTP redirect to a custom controller if one is found.
  1048.      *
  1049.      * @param string $BOName The classname of the business object
  1050.      * @param string $mode The mode of the controller (create, view, edit)
  1051.      * @throws FileNotFoundException
  1052.      * @since 1.0
  1053.      */
  1054.     protected function loadCustomController($BOName$mode{
  1055.         self::$logger->debug('>>loadCustomController(BOName=['.$BOName.'], mode=['.$mode.'])');
  1056.         
  1057.         global $config;
  1058.         
  1059.         // strip the Object part from the class name
  1060.         $BOName substr($BOName0strpos($BOName'Object'));
  1061.         // uppercase the first letter of each word, e.g. create cart becomes Create Cart
  1062.         $controllerName ucwords($mode.' '.$BOName);
  1063.         // remove spaces
  1064.         $controllerName str_replace(' '''$controllerName);
  1065.  
  1066.         self::$logger->debug('Custom controller name is ['.$controllerName.']');
  1067.         
  1068.         // just making sure that we are not already using the custom controller
  1069.         if(get_class($this!= $controllerName{
  1070.             if (file_exists($config->get('sysRoot').'controller/'.$controllerName.'.php')) {
  1071.                 self::$logger->debug('Custom controller found, redirecting...');
  1072.                 // handle secure URLs
  1073.                 if(isset($_GET['tk'])) {
  1074.                     $params FrontController::decodeQueryParams($_GET['tk']);
  1075.                     $params preg_replace('/act=.*\&/''act='.$controllerName.'&'$params);
  1076.                     self::$logger->debug('Params are ['.$params.']');
  1077.                     
  1078.                     $url FrontController::generateSecureURL($params);
  1079.                     self::$logger->debug('Redirecting to ['.$url.']');
  1080.                     header('Location: '.$url);
  1081.                     self::$logger->debug('<<loadCustomController');
  1082.                     exit;
  1083.                 }else{
  1084.                     $url $config->get('sysURL').'controller/'.$controllerName.'.php?'.$_SERVER['QUERY_STRING'];
  1085.                     self::$logger->debug('Redirecting to ['.$url.']');
  1086.                     header('Location: '.$url);
  1087.                     self::$logger->debug('<<loadCustomController');
  1088.                     exit;
  1089.                 }
  1090.             }elseif (file_exists($config->get('sysRoot').'alpha/controller/'.$controllerName.'.php')) {
  1091.                 self::$logger->debug('Custom controller found, redirecting...');
  1092.                 // handle secure URLs
  1093.                 if(self::checkIfAccessingFromSecureURL()) {
  1094.                     if(isset($_GET['tk'])) {
  1095.                         $params FrontController::decodeQueryParams($_GET['tk']);
  1096.                     }else{
  1097.                         $start strpos($_SERVER['REQUEST_URI']'/tk/')+3;
  1098.                         $end strlen($_SERVER['REQUEST_URI']);
  1099.                         $tk substr($_SERVER['REQUEST_URI']$start+1$end-($start+1));
  1100.                         $params FrontController::decodeQueryParams($tk);
  1101.                     }
  1102.                     
  1103.                     $params preg_replace('/act=.*\&/''act='.$controllerName.'&'$params);
  1104.                     self::$logger->debug('Params are ['.$params.']');
  1105.                     
  1106.                     $url FrontController::generateSecureURL($params);
  1107.                     self::$logger->debug('Redirecting to ['.$url.']');
  1108.                     header('Location: '.$url);
  1109.                     self::$logger->debug('<<loadCustomController');
  1110.                     exit;
  1111.                 }else{
  1112.                     $url $config->get('sysURL').'alpha/controller/'.$controllerName.'.php?'.$_SERVER['QUERY_STRING'];
  1113.                     self::$logger->debug('Redirecting to ['.$url.']');
  1114.                     header('Location: '.$url);
  1115.                     self::$logger->debug('<<loadCustomController');
  1116.                     exit;
  1117.                 }    
  1118.             }else{
  1119.                 // throw an exception if we have gotten this far and no custom controller was found
  1120.                 throw new FileNotFoundException('The controller ['.$controllerName.'] could not be loaded as it does not exist');
  1121.             }
  1122.         }
  1123.         
  1124.         self::$logger->debug('<<loadCustomController');
  1125.     }
  1126.     
  1127.     /**
  1128.      * Set the status message in the _SESSION to the value provided.
  1129.      * 
  1130.      * @param string $message 
  1131.      * @since 1.0
  1132.      */
  1133.     public function setStatusMessage($message{
  1134.         $this->statusMessage = $message;
  1135.         $_SESSION['statusMessage'$message;
  1136.     }
  1137.     
  1138.     /**
  1139.      * Gets the current status message for this controller.  Note that by getting the current
  1140.      * status message, you clear out the value stored in _SESSION so this method can only be used
  1141.      * to get the status message once for display purposes.
  1142.      * 
  1143.      * @return string 
  1144.      * @since 1.0
  1145.      */
  1146.     public function getStatusMessage({
  1147.         $_SESSION['statusMessage'null;
  1148.         return $this->statusMessage;
  1149.     }
  1150.     
  1151.     /**
  1152.      * Checks that the definition for the controller classname provided exists.  Will also return true
  1153.      * if you pass "/" for the root of the web application.
  1154.      * 
  1155.      * @param string $controllerName 
  1156.      * @return boolean 
  1157.      * @since 1.0
  1158.      */
  1159.     public static function checkControllerDefExists($controllerName{
  1160.         if(self::$logger == null)
  1161.             self::$logger new Logger('AlphaController');
  1162.         self::$logger->debug('>>checkControllerDefExists(controllerName=['.$controllerName.'])');
  1163.         
  1164.         global $config;
  1165.         
  1166.         $exists false;
  1167.         
  1168.         if($controllerName == '/')
  1169.             $exists true;
  1170.         if(file_exists($config->get('sysRoot').'controller/'.$controllerName.'.php'))
  1171.             $exists true;
  1172.         if(file_exists($config->get('sysRoot').'alpha/controller/'.$controllerName.'.php'))
  1173.             $exists true;
  1174.  
  1175.         self::$logger->debug('<<checkControllerDefExists ['.$exists.']');
  1176.         return $exists;
  1177.     }
  1178.     
  1179.     /**
  1180.      * Loads the definition for the controller classname provided.
  1181.      * 
  1182.      * @param string $controllerName 
  1183.      * @throws IllegalArguementException
  1184.      * @since 1.0
  1185.      */
  1186.     public static function loadControllerDef($controllerName{
  1187.         if(self::$logger == null)
  1188.             self::$logger new Logger('AlphaController');
  1189.         self::$logger->debug('>>loadControllerDef(controllerName=['.$controllerName.'])');
  1190.         
  1191.         global $config;
  1192.         
  1193.         if(file_exists($config->get('sysRoot').'controller/'.$controllerName.'.php'))
  1194.             require_once $config->get('sysRoot').'controller/'.$controllerName.'.php';
  1195.         elseif(file_exists($config->get('sysRoot').'alpha/controller/'.$controllerName.'.php'))
  1196.             require_once $config->get('sysRoot').'alpha/controller/'.$controllerName.'.php';
  1197.         else
  1198.             throw new IllegalArguementException('The class ['.$controllerName.'] is not defined anywhere!');
  1199.         
  1200.         self::$logger->debug('<<loadControllerDef');
  1201.     }
  1202.     
  1203.     /**
  1204.      * Static function for determining if the current request URL is a secure one (has a tk string or not)
  1205.      * 
  1206.      * @return boolean True if the current URL contains a tk value, false otherwise
  1207.      * @since 1.0
  1208.      */
  1209.     public static function checkIfAccessingFromSecureURL({
  1210.         if (isset($_GET['tk']|| strpos($_SERVER['REQUEST_URI']'/tk/'!== false)
  1211.             return true;
  1212.         else
  1213.             return false;
  1214.     }
  1215. }
  1216.  
  1217. ?>

Documentation generated on Tue, 13 Dec 2011 20:25:36 +0000 by phpDocumentor 1.4.3