more comment fixes
[civicrm-core.git] / CRM / Core / Form / RecurringEntity.php
index 975985562d57bf5e2069b6862b1113eabc35c8c6..c202188193ec1bcdee0e4a240d4fe6a7f8c49220 100644 (file)
-<?php\r
-/*\r
- +--------------------------------------------------------------------+\r
- | CiviCRM version 4.4                                                |\r
- +--------------------------------------------------------------------+\r
- | Copyright CiviCRM LLC (c) 2004-2013                                |\r
- +--------------------------------------------------------------------+\r
- | This file is a part of CiviCRM.                                    |\r
- |                                                                    |\r
- | CiviCRM is free software; you can copy, modify, and distribute it  |\r
- | under the terms of the GNU Affero General Public License           |\r
- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |\r
- |                                                                    |\r
- | CiviCRM is distributed in the hope that it will be useful, but     |\r
- | WITHOUT ANY WARRANTY; without even the implied warranty of         |\r
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |\r
- | See the GNU Affero General Public License for more details.        |\r
- |                                                                    |\r
- | You should have received a copy of the GNU Affero General Public   |\r
- | License and the CiviCRM Licensing Exception along                  |\r
- | with this program; if not, contact CiviCRM LLC                     |\r
- | at info[AT]civicrm[DOT]org. If you have questions about the        |\r
- | GNU Affero General Public License or the licensing of CiviCRM,     |\r
- | see the CiviCRM license FAQ at http://civicrm.org/licensing        |\r
- +--------------------------------------------------------------------+\r
-*/\r
-\r
-/**\r
- *\r
- *\r
- * @package CRM\r
- * @copyright CiviCRM LLC (c) 2004-2013\r
- * $Id$\r
- *\r
- */\r
-/**\r
- * This class generates form components for processing Entity\r
- *\r
- */\r
-class CRM_Core_Form_RecurringEntity {\r
-  /**\r
-   *  Current entity id\r
-   */\r
-  protected static $_entityId = NULL;\r
-\r
-  /**\r
-   * Schedule Reminder ID\r
-   */\r
-  protected static $_scheduleReminderID = NULL;\r
-\r
-  /**\r
-  * Schedule Reminder data\r
-  */\r
-  protected static $_scheduleReminderDetails = array();\r
-\r
-  /**\r
-  *  Parent Entity ID\r
-  */\r
-  protected static $_parentEntityId = NULL;\r
-\r
-  /**\r
-  * Exclude date information\r
-  */\r
-  public static $_excludeDateInfo = array();\r
-\r
-  /**\r
-  * Entity Table\r
-  */\r
-  public static $_entityTable;\r
-\r
-  /**\r
-   * Checks current entityID has parent\r
-   */\r
-  public static $_hasParent = FALSE;\r
-\r
-  static function preProcess($entityTable) {\r
-    self::$_entityId = (int) CRM_Utils_Request::retrieve('id', 'Positive');\r
-    self::$_entityTable = $entityTable;\r
-\r
-    if (self::$_entityId && $entityTable) {\r
-      $checkParentExistsForThisId = CRM_Core_BAO_RecurringEntity::getParentFor(self::$_entityId, $entityTable);\r
-      if ($checkParentExistsForThisId) {\r
-        self::$_hasParent = TRUE;\r
-        self::$_parentEntityId = $checkParentExistsForThisId;\r
-        self::$_scheduleReminderDetails = CRM_Core_BAO_RecurringEntity::getReminderDetailsByEntityId($checkParentExistsForThisId, $entityTable);\r
-      }\r
-      else {\r
-        self::$_parentEntityId = self::$_entityId;\r
-        self::$_scheduleReminderDetails = CRM_Core_BAO_RecurringEntity::getReminderDetailsByEntityId(self::$_entityId, $entityTable);\r
-      }\r
-      if (property_exists(self::$_scheduleReminderDetails, 'id')) {\r
-        self::$_scheduleReminderID = self::$_scheduleReminderDetails->id;\r
-      }\r
-    }\r
-    if ($entityTable) {\r
-      CRM_Core_OptionValue::getValues(array('name' => $entityTable.'_repeat_exclude_dates_'.self::$_parentEntityId), $optionValue);\r
-      $excludeOptionValues = array();\r
-      if (!empty($optionValue)) {\r
-        foreach($optionValue as $key => $val) {\r
-          $excludeOptionValues[$val['value']] = date('m/d/Y', strtotime($val['value']));\r
-        }\r
-        self::$_excludeDateInfo = $excludeOptionValues;\r
-      }\r
-    }\r
-  }\r
-\r
-   /**\r
-   * Set default values for the form. For edit/view mode\r
-   * the default values are retrieved from the database\r
-   *\r
-   * @access public\r
-   *\r
-   * @return None\r
-   */\r
-  static function setDefaultValues() {\r
-    $defaults = array();\r
-    if (self::$_scheduleReminderID) {\r
-      $defaults['repetition_frequency_unit'] = self::$_scheduleReminderDetails->repetition_frequency_unit;\r
-      $defaults['repetition_frequency_interval'] = self::$_scheduleReminderDetails->repetition_frequency_interval;\r
-      $defaults['start_action_condition'] = array_flip(explode(",",self::$_scheduleReminderDetails->start_action_condition));\r
-      foreach($defaults['start_action_condition'] as $key => $val) {\r
-        $val = 1;\r
-        $defaults['start_action_condition'][$key] = $val;\r
-      }\r
-      $defaults['start_action_offset'] = self::$_scheduleReminderDetails->start_action_offset;\r
-      if (self::$_scheduleReminderDetails->start_action_offset) {\r
-        $defaults['ends'] = 1;\r
-      }\r
-      list($defaults['repeat_absolute_date']) = CRM_Utils_Date::setDateDefaults(self::$_scheduleReminderDetails->absolute_date);\r
-      if (self::$_scheduleReminderDetails->absolute_date) {\r
-        $defaults['ends'] = 2;\r
-      }\r
-      $defaults['limit_to'] = self::$_scheduleReminderDetails->limit_to;\r
-      if (self::$_scheduleReminderDetails->limit_to) {\r
-        $defaults['repeats_by'] = 1;\r
-      }\r
-      $explodeStartActionCondition = array();\r
-      if (self::$_scheduleReminderDetails->entity_status) {\r
-        $explodeStartActionCondition = explode(" ", self::$_scheduleReminderDetails->entity_status);\r
-        $defaults['entity_status_1'] = $explodeStartActionCondition[0];\r
-        $defaults['entity_status_2'] = $explodeStartActionCondition[1];\r
-      }\r
-      if (self::$_scheduleReminderDetails->entity_status) {\r
-        $defaults['repeats_by'] = 2;\r
-      }\r
-    }\r
-    return $defaults;\r
-  }\r
-\r
-  static function buildQuickForm(&$form) {\r
-    if (self::$_entityTable) {\r
-      $entityType = explode("_", self::$_entityTable);\r
-      if ($entityType[1]) {\r
-        $form->assign('entityType', ucwords($entityType[1]));\r
-      }\r
-    }\r
-    $form->assign('currentEntityId', self::$_entityId);\r
-    $form->assign('entityTable', self::$_entityTable);\r
-    $form->assign('scheduleReminderId', self::$_scheduleReminderID);\r
-    $form->assign('hasParent', self::$_hasParent);\r
-\r
-    $form->_freqUnits = array('hour' => 'hour') + CRM_Core_OptionGroup::values('recur_frequency_units');\r
-    foreach ($form->_freqUnits as $val => $label) {\r
-      if ($label == "day") {\r
-          $label = "dai";\r
-      }\r
-      $freqUnitsDisplay[$val] = ts('%1ly', array(1 => $label));\r
-    }\r
-   // echo "<pre>";print_r($freqUnitsDisplay);\r
-    $dayOfTheWeek = array('monday'   => 'Monday',\r
-                          'tuesday'   => 'Tuesday',\r
-                          'wednesday' => 'Wednesday',\r
-                          'thursday'  => 'Thursday',\r
-                          'friday'    => 'Friday',\r
-                          'saturday'  => 'Saturday',\r
-                          'sunday'    => 'Sunday'\r
-                         );\r
-    $form->add('select', 'repetition_frequency_unit', ts('Repeats:'), $freqUnitsDisplay);\r
-    $numericOptions = CRM_Core_SelectValues::getNumericOptions(1, 30);\r
-    $form->add('select', 'repetition_frequency_interval', ts('Repeats every:'), $numericOptions, '', array('style' => 'width:55px;'));\r
-    $form->addDateTime('repetition_start_date', ts('Repetition Start Date'), FALSE, array('formatType' => 'activityDateTime'));\r
-    foreach($dayOfTheWeek as $key => $val) {\r
-        $startActionCondition[] = $form->createElement('checkbox', $key, NULL, substr($val."&nbsp;", 0, 3));\r
-    }\r
-    $form->addGroup($startActionCondition, 'start_action_condition', ts('Repeats on'));\r
-    $roptionTypes = array('1' => ts('day of the month'),\r
-        '2' => ts('day of the week'),\r
-      );\r
-    $form->addRadio('repeats_by', ts("Repeats By:"), $roptionTypes, array(), NULL);\r
-    $getMonths = CRM_Core_SelectValues::getNumericOptions(1, 31);\r
-    $form->add('select', 'limit_to', '', $getMonths, FALSE, array('style' => 'width:55px;'));\r
-    $dayOfTheWeekNo = array('first'  => 'First',\r
-                            'second'=> 'Second',\r
-                            'third' => 'Third',\r
-                            'fourth'=> 'Fourth',\r
-                            'last'  => 'Last'\r
-                         );\r
-    $form->add('select', 'entity_status_1', ts(''), $dayOfTheWeekNo);\r
-    $form->add('select', 'entity_status_2', ts(''), $dayOfTheWeek);\r
-    $eoptionTypes = array('1' => ts('After'),\r
-        '2' => ts('On'),\r
-      );\r
-    $form->addRadio('ends', ts("Ends:"), $eoptionTypes, array(), NULL);\r
-    $form->add('text', 'start_action_offset', ts(''), array('size' => 3, 'maxlength' => 2));\r
-    $form->addFormRule(array('CRM_Core_Form_RecurringEntity', 'formRule'));\r
-    $form->addDate('repeat_absolute_date', ts('On'), FALSE, array('formatType' => 'mailing'));\r
-    $form->addDate('exclude_date', ts('Exclude Date(s)'), FALSE);\r
-    $select = $form->add('select', 'exclude_date_list', ts(''), self::$_excludeDateInfo, FALSE, array('style' => 'width:150px;', 'size' => 4));\r
-    $select->setMultiple(TRUE);\r
-    $form->addElement('button','add_to_exclude_list','>>','onClick="addToExcludeList(document.getElementById(\'exclude_date\').value);"');\r
-    $form->addElement('button','remove_from_exclude_list', '<<', 'onClick="removeFromExcludeList(\'exclude_date_list\')"');\r
-    $form->addElement('hidden', 'copyExcludeDates', '', array('id' => 'copyExcludeDates'));\r
-    $form->addElement('hidden', 'allowRepeatConfigToSubmit', '', array('id' => 'allowRepeatConfigToSubmit'));\r
-    $form->addButtons(array(\r
-        array(\r
-          'type' => 'submit',\r
-          'name' => ts('Save'),\r
-          'isDefault' => TRUE,\r
-        ),\r
-        array(\r
-          'type' => 'cancel',\r
-          'name' => ts('Cancel')\r
-        ),\r
-      )\r
-    );\r
-  }\r
-\r
-  /**\r
-   * Global validation rules for the form\r
-   *\r
-   * @param array $fields posted values of the form\r
-   *\r
-   * @return array list of errors to be posted back to the form\r
-   * @static\r
-   * @access public\r
-   */\r
-  static function formRule($values) {\r
-    $errors = array();\r
-    //Process this function only when you get this variable\r
-    if ($values['allowRepeatConfigToSubmit'] == 1) {\r
-      $dayOfTheWeek = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');\r
-      //Repeats\r
-      if (!CRM_Utils_Array::value('repetition_frequency_unit', $values)) {\r
-        $errors['repetition_frequency_unit'] = ts('This is a required field');\r
-      }\r
-      //Repeats every\r
-      if (!CRM_Utils_Array::value('repetition_frequency_interval', $values)) {\r
-        $errors['repetition_frequency_interval'] = ts('This is a required field');\r
-      }\r
-      //Ends\r
-      if (CRM_Utils_Array::value('ends', $values)) {\r
-        if ($values['ends'] == 1) {\r
-          if (empty($values['start_action_offset'])) {\r
-            $errors['start_action_offset'] = ts('This is a required field');\r
-          }\r
-          else if ($values['start_action_offset'] > 30) {\r
-            $errors['start_action_offset'] = ts('Occurrences should be less than or equal to 30');\r
-          }\r
-        }\r
-        if ($values['ends'] == 2) {\r
-          if (CRM_Utils_Array::value('repeat_absolute_date', $values)) {\r
-            $entityStartDate = CRM_Utils_Date::processDate($values['repetition_start_date']);\r
-            $end = CRM_Utils_Date::processDate($values['repeat_absolute_date']);\r
-            if (($end < $entityStartDate) && ($end != 0)) {\r
-              $errors['repeat_absolute_date'] = ts('End date should be after current entity\'s start date');\r
-            }\r
-          }\r
-          else {\r
-            $errors['repeat_absolute_date'] = ts('This is a required field');\r
-          }\r
-        }\r
-      }\r
-      else {\r
-        $errors['ends'] = ts('This is a required field');\r
-      }\r
-\r
-      //Repeats BY\r
-      if (CRM_Utils_Array::value('repeats_by', $values)) {\r
-        if ($values['repeats_by'] == 1) {\r
-          if (CRM_Utils_Array::value('limit_to', $values)) {\r
-            if ($values['limit_to'] < 1 && $values['limit_to'] > 31) {\r
-              $errors['limit_to'] = ts('Invalid day of the month');\r
-            }\r
-          }\r
-          else {\r
-            $errors['limit_to'] = ts('Invalid day of the month');\r
-          }\r
-        }\r
-        if ($values['repeats_by'] == 2) {\r
-          if (CRM_Utils_Array::value('entity_status_1', $values)) {\r
-            $dayOfTheWeekNo = array(first, second, third, fourth, last);\r
-            if (!in_array($values['entity_status_1'], $dayOfTheWeekNo)) {\r
-               $errors['entity_status_1'] = ts('Invalid option');\r
-            }\r
-          }\r
-          else {\r
-            $errors['entity_status_1'] = ts('Invalid option');\r
-          }\r
-          if (CRM_Utils_Array::value('entity_status_2', $values)) {\r
-            if (!in_array($values['entity_status_2'], $dayOfTheWeek)) {\r
-               $errors['entity_status_2'] = ts('Invalid day name');\r
-            }\r
-          }\r
-          else {\r
-            $errors['entity_status_2'] = ts('Invalid day name');\r
-          }\r
-        }\r
-      }\r
-    }\r
-    return $errors;\r
-  }\r
-\r
-  /**\r
-   * Process the form submission\r
-   *\r
-   * @access public\r
-   *\r
-   * @return None\r
-   */\r
-  static function postProcess($params = array(), $type, $linkedEntities = array()) {\r
-    //Check entity_id not present in params take it from class variable\r
-    if (!CRM_Utils_Array::value('entity_id', $params)) {\r
-      $params['entity_id'] = self::$_entityId;\r
-    }\r
-    //Process this function only when you get this variable\r
-    if ($params['allowRepeatConfigToSubmit'] == 1) {\r
-      if (CRM_Utils_Array::value('entity_table', $params) && CRM_Utils_Array::value('entity_id', $params) && $type) {\r
-        $params['used_for'] = $type;\r
-        if (!CRM_Utils_Array::value('parent_entity_id', $params)) {\r
-          $params['parent_entity_id'] = self::$_parentEntityId;\r
-        }\r
-        if (CRM_Utils_Array::value('schedule_reminder_id', $params)) {\r
-          $params['id'] = $params['schedule_reminder_id'];\r
-        }\r
-        else {\r
-          $params['id'] = self::$_scheduleReminderID;\r
-        }\r
-\r
-        //Save post params to the schedule reminder table\r
-        $recurobj = new CRM_Core_BAO_RecurringEntity();\r
-        $dbParams = $recurobj->mapFormValuesToDB($params);\r
-\r
-        //Delete repeat configuration and rebuild\r
-        if (CRM_Utils_Array::value('id', $params)) {\r
-          CRM_Core_BAO_ActionSchedule::del($params['id']);\r
-          unset($params['id']);\r
-        }\r
-        $actionScheduleObj = CRM_Core_BAO_ActionSchedule::add($dbParams);\r
-\r
-        //exclude dates\r
-        $excludeDateList = array();\r
-        if (CRM_Utils_Array::value('copyExcludeDates', $params) && CRM_Utils_Array::value('parent_entity_id', $params) && $actionScheduleObj->entity_value) {\r
-          //Since we get comma separated values lets get them in array\r
-          $excludeDates = array();\r
-          $excludeDates = explode(",", $params['copyExcludeDates']);\r
-\r
-          //Check if there exists any values for this option group\r
-          $optionGroupIdExists = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup',\r
-              $type.'_repeat_exclude_dates_'.$params['parent_entity_id'],\r
-              'id',\r
-              'name'\r
-            );\r
-          if ($optionGroupIdExists) {\r
-            CRM_Core_BAO_OptionGroup::del($optionGroupIdExists);\r
-          }\r
-          $optionGroupParams =\r
-              array(\r
-                'name'        => $type.'_repeat_exclude_dates_'.$actionScheduleObj->entity_value,\r
-                'title'       => $type.' recursion',\r
-                'is_reserved' => 0,\r
-                'is_active'   => 1\r
-              );\r
-          $opGroup = CRM_Core_BAO_OptionGroup::add($optionGroupParams);\r
-          if ($opGroup->id) {\r
-            $oldWeight= 0;\r
-            $fieldValues = array('option_group_id' => $opGroup->id);\r
-            foreach($excludeDates as $val) {\r
-              $optionGroupValue =\r
-                  array(\r
-                    'option_group_id' =>  $opGroup->id,\r
-                    'label'           =>  CRM_Utils_Date::processDate($val),\r
-                    'value'           =>  CRM_Utils_Date::processDate($val),\r
-                    'name'            =>  $opGroup->name,\r
-                    'description'     =>  'Used for recurring '.$type,\r
-                    'weight'          =>  CRM_Utils_Weight::updateOtherWeights('CRM_Core_DAO_OptionValue', $oldWeight, CRM_Utils_Array::value('weight', $params), $fieldValues),\r
-                    'is_active'       =>  1\r
-                  );\r
-              $excludeDateList[] = $optionGroupValue['value'];\r
-              CRM_Core_BAO_OptionValue::add($optionGroupValue);\r
-            }\r
-          }\r
-        }\r
-\r
-        //Set type for API\r
-        $apiEntityType = array();\r
-        $apiEntityType = explode("_", $type);\r
-        if (!empty($apiEntityType[1])) {\r
-          $apiType = $apiEntityType[1];\r
-        }\r
-        //Delete relations if any from recurring entity tables before inserting new relations for this entity id\r
-        if ($params['entity_id']) {\r
-          //If entity has any pre delete function, consider that first\r
-          if (CRM_Utils_Array::value('pre_delete_func', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]) &&\r
-              CRM_Utils_Array::value('helper_class', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']])) {\r
-              call_user_func(array(\r
-                CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['helper_class'],\r
-                call_user_func_array(CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['pre_delete_func'], array($params['entity_id'])))\r
-              );\r
-          }\r
-          //Ready to execute delete on entities if it has delete function set\r
-          if (CRM_Utils_Array::value('delete_func', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]) &&\r
-            CRM_Utils_Array::value('helper_class', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']])) {\r
-            //Check if pre delete function has some ids to be deleted\r
-            if (!empty(CRM_Core_BAO_RecurringEntity::$_entitiesToBeDeleted)) {\r
-              foreach (CRM_Core_BAO_RecurringEntity::$_entitiesToBeDeleted as $eid) {\r
-                $result = civicrm_api3(\r
-                  ucfirst(strtolower($apiType)),\r
-                  CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['delete_func'],\r
-                  array(\r
-                    'sequential' => 1,\r
-                    'id' => $eid,\r
-                  )\r
-                );\r
-                if ($result['error']) {\r
-                  CRM_Core_Error::statusBounce('Error creating recurring list');\r
-                }\r
-              }\r
-            }\r
-            else {\r
-              $getRelatedEntities = CRM_Core_BAO_RecurringEntity::getEntitiesFor($params['entity_id'], $params['entity_table'], FALSE);\r
-              foreach ($getRelatedEntities as $key => $value) {\r
-                $result = civicrm_api3(\r
-                  ucfirst(strtolower($apiType)),\r
-                  CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['delete_func'],\r
-                  array(\r
-                    'sequential' => 1,\r
-                    'id' => $value['id'],\r
-                  )\r
-                );\r
-                if ($result['error']) {\r
-                  CRM_Core_Error::statusBounce('Error creating recurring list');\r
-                }\r
-              }\r
-            }\r
-          }\r
-\r
-          // find all entities from the recurring set. At this point we 'll get entities which were not deleted \r
-          // for e.g due to participants being present. We need to delete them from recurring tables anyway.\r
-          $pRepeatingEntities = CRM_Core_BAO_RecurringEntity::getEntitiesFor($params['entity_id'], $params['entity_table']);\r
-          foreach($pRepeatingEntities as $val) {\r
-            CRM_Core_BAO_RecurringEntity::delEntity($val['id'], $val['table'], TRUE);\r
-          }\r
-        }\r
-\r
-        $recursion = new CRM_Core_BAO_RecurringEntity();\r
-        $recursion->dateColumns  = $params['dateColumns'];\r
-        $recursion->scheduleId   = $actionScheduleObj->id;\r
-\r
-        if (!empty($excludeDateList)) {\r
-          $recursion->excludeDates = $excludeDateList;\r
-          $recursion->excludeDateRangeColumns = $params['excludeDateRangeColumns'];\r
-        }\r
-        if (CRM_Utils_Array::value('intervalDateColumns', $params)) {\r
-          $recursion->intervalDateColumns = $params['intervalDateColumns'];\r
-        }\r
-        $recursion->entity_id = $params['entity_id'];\r
-        $recursion->entity_table = $params['entity_table'];\r
-        if (!empty($linkedEntities)) {\r
-          $recursion->linkedEntities = $linkedEntities;\r
-        }\r
-\r
-        $recurResult = $recursion->generate();\r
-\r
-        $status = ts('Repeat Configuration has been saved');\r
-        CRM_Core_Session::setStatus($status, ts('Saved'), 'success');\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Return a descriptive name for the page, used in wizard header\r
-   *\r
-   * @return string\r
-   * @access public\r
-   */\r
-  public function getTitle() {\r
-    return ts('Repeat Entity');\r
-  }\r
-\r
-}\r
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.6                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2014
+ * $Id$
+ *
+ */
+
+/**
+ * This class generates form components for processing Entity
+ *
+ */
+class CRM_Core_Form_RecurringEntity {
+  /**
+   *  Current entity id
+   */
+  protected static $_entityId = NULL;
+
+  /**
+   * Schedule Reminder ID
+   */
+  protected static $_scheduleReminderID = NULL;
+
+  /**
+   * Schedule Reminder data
+   */
+  protected static $_scheduleReminderDetails = array();
+
+  /**
+   *  Parent Entity ID
+   */
+  protected static $_parentEntityId = NULL;
+
+  /**
+   * Exclude date information
+   */
+  public static $_excludeDateInfo = array();
+
+  /**
+   * Entity Table
+   */
+  public static $_entityTable;
+
+  /**
+   * Checks current entityID has parent
+   */
+  public static $_hasParent = FALSE;
+
+  /**
+   * @param $entityTable
+   */
+  public static function preProcess($entityTable) {
+    self::$_entityId = (int) CRM_Utils_Request::retrieve('id', 'Positive');
+    self::$_entityTable = $entityTable;
+
+    if (self::$_entityId && $entityTable) {
+      $checkParentExistsForThisId = CRM_Core_BAO_RecurringEntity::getParentFor(self::$_entityId, $entityTable);
+      if ($checkParentExistsForThisId) {
+        self::$_hasParent = TRUE;
+        self::$_parentEntityId = $checkParentExistsForThisId;
+        self::$_scheduleReminderDetails = CRM_Core_BAO_RecurringEntity::getReminderDetailsByEntityId($checkParentExistsForThisId, $entityTable);
+      }
+      else {
+        self::$_parentEntityId = self::$_entityId;
+        self::$_scheduleReminderDetails = CRM_Core_BAO_RecurringEntity::getReminderDetailsByEntityId(self::$_entityId, $entityTable);
+      }
+      if (property_exists(self::$_scheduleReminderDetails, 'id')) {
+        self::$_scheduleReminderID = self::$_scheduleReminderDetails->id;
+      }
+    }
+    if ($entityTable) {
+      CRM_Core_OptionValue::getValues(array('name' => $entityTable . '_repeat_exclude_dates_' . self::$_parentEntityId), $optionValue);
+      $excludeOptionValues = array();
+      if (!empty($optionValue)) {
+        foreach ($optionValue as $key => $val) {
+          $excludeOptionValues[$val['value']] = date('m/d/Y', strtotime($val['value']));
+        }
+        self::$_excludeDateInfo = $excludeOptionValues;
+      }
+    }
+  }
+
+  /**
+   * Set default values for the form. For edit/view mode
+   * the default values are retrieved from the database
+   *
+   *
+   * @return array
+   */
+  public static function setDefaultValues() {
+    $defaults = array();
+    if (self::$_scheduleReminderID) {
+      $defaults['repetition_frequency_unit'] = self::$_scheduleReminderDetails->repetition_frequency_unit;
+      $defaults['repetition_frequency_interval'] = self::$_scheduleReminderDetails->repetition_frequency_interval;
+      $defaults['start_action_condition'] = array_flip(explode(",", self::$_scheduleReminderDetails->start_action_condition));
+      foreach ($defaults['start_action_condition'] as $key => $val) {
+        $val = 1;
+        $defaults['start_action_condition'][$key] = $val;
+      }
+      $defaults['start_action_offset'] = self::$_scheduleReminderDetails->start_action_offset;
+      if (self::$_scheduleReminderDetails->start_action_offset) {
+        $defaults['ends'] = 1;
+      }
+      list($defaults['repeat_absolute_date']) = CRM_Utils_Date::setDateDefaults(self::$_scheduleReminderDetails->absolute_date);
+      if (self::$_scheduleReminderDetails->absolute_date) {
+        $defaults['ends'] = 2;
+      }
+      $defaults['limit_to'] = self::$_scheduleReminderDetails->limit_to;
+      if (self::$_scheduleReminderDetails->limit_to) {
+        $defaults['repeats_by'] = 1;
+      }
+      $explodeStartActionCondition = array();
+      if (self::$_scheduleReminderDetails->entity_status) {
+        $explodeStartActionCondition = explode(" ", self::$_scheduleReminderDetails->entity_status);
+        $defaults['entity_status_1'] = $explodeStartActionCondition[0];
+        $defaults['entity_status_2'] = $explodeStartActionCondition[1];
+      }
+      if (self::$_scheduleReminderDetails->entity_status) {
+        $defaults['repeats_by'] = 2;
+      }
+    }
+    return $defaults;
+  }
+
+  /**
+   * Build form.
+   *
+   * @param $form
+   */
+  public static function buildQuickForm(&$form) {
+    if (self::$_entityTable) {
+      $entityType = explode("_", self::$_entityTable);
+      if ($entityType[1]) {
+        $form->assign('entityType', ucwords($entityType[1]));
+      }
+    }
+    $form->assign('currentEntityId', self::$_entityId);
+    $form->assign('entityTable', self::$_entityTable);
+    $form->assign('scheduleReminderId', self::$_scheduleReminderID);
+    $form->assign('hasParent', self::$_hasParent);
+
+    $form->_freqUnits = array('hour' => 'hour') + CRM_Core_OptionGroup::values('recur_frequency_units');
+    foreach ($form->_freqUnits as $val => $label) {
+      if ($label == "day") {
+        $label = "dai";
+      }
+      $freqUnitsDisplay[$val] = ts('%1ly', array(1 => $label));
+    }
+    // echo "<pre>";print_r($freqUnitsDisplay);
+    $dayOfTheWeek = array(
+      'monday' => 'Monday',
+      'tuesday' => 'Tuesday',
+      'wednesday' => 'Wednesday',
+      'thursday' => 'Thursday',
+      'friday' => 'Friday',
+      'saturday' => 'Saturday',
+      'sunday' => 'Sunday',
+    );
+    $form->add('select', 'repetition_frequency_unit', ts('Repeats:'), $freqUnitsDisplay);
+    $numericOptions = CRM_Core_SelectValues::getNumericOptions(1, 30);
+    $form->add('select', 'repetition_frequency_interval', ts('Repeats every:'), $numericOptions, '', array('style' => 'width:55px;'));
+    $form->addDateTime('repetition_start_date', ts('Repetition Start Date'), FALSE, array('formatType' => 'activityDateTime'));
+    foreach ($dayOfTheWeek as $key => $val) {
+      $startActionCondition[] = $form->createElement('checkbox', $key, NULL, substr($val . "&nbsp;", 0, 3));
+    }
+    $form->addGroup($startActionCondition, 'start_action_condition', ts('Repeats on'));
+    $roptionTypes = array(
+      '1' => ts('day of the month'),
+      '2' => ts('day of the week'),
+    );
+    $form->addRadio('repeats_by', ts("Repeats By:"), $roptionTypes, array(), NULL);
+    $getMonths = CRM_Core_SelectValues::getNumericOptions(1, 31);
+    $form->add('select', 'limit_to', '', $getMonths, FALSE, array('style' => 'width:55px;'));
+    $dayOfTheWeekNo = array(
+      'first' => 'First',
+      'second' => 'Second',
+      'third' => 'Third',
+      'fourth' => 'Fourth',
+      'last' => 'Last',
+    );
+    $form->add('select', 'entity_status_1', ts(''), $dayOfTheWeekNo);
+    $form->add('select', 'entity_status_2', ts(''), $dayOfTheWeek);
+    $eoptionTypes = array(
+      '1' => ts('After'),
+      '2' => ts('On'),
+    );
+    $form->addRadio('ends', ts("Ends:"), $eoptionTypes, array(), NULL);
+    $form->add('text', 'start_action_offset', ts(''), array('size' => 3, 'maxlength' => 2));
+    $form->addFormRule(array('CRM_Core_Form_RecurringEntity', 'formRule'));
+    $form->addDate('repeat_absolute_date', ts('On'), FALSE, array('formatType' => 'mailing'));
+    $form->addDate('exclude_date', ts('Exclude Date(s)'), FALSE);
+    $select = $form->add('select', 'exclude_date_list', ts(''), self::$_excludeDateInfo, FALSE, array(
+        'style' => 'width:150px;',
+        'size' => 4,
+      ));
+    $select->setMultiple(TRUE);
+    $form->addElement('button', 'add_to_exclude_list', '>>', 'onClick="addToExcludeList(document.getElementById(\'exclude_date\').value);"');
+    $form->addElement('button', 'remove_from_exclude_list', '<<', 'onClick="removeFromExcludeList(\'exclude_date_list\')"');
+    $form->addElement('hidden', 'copyExcludeDates', '', array('id' => 'copyExcludeDates'));
+    $form->addElement('hidden', 'allowRepeatConfigToSubmit', '', array('id' => 'allowRepeatConfigToSubmit'));
+    $form->addButtons(array(
+        array(
+          'type' => 'submit',
+          'name' => ts('Save'),
+          'isDefault' => TRUE,
+        ),
+        array(
+          'type' => 'cancel',
+          'name' => ts('Cancel'),
+        ),
+      )
+    );
+  }
+
+  /**
+   * Global validation rules for the form
+   *
+   * @param array $values
+   *   Posted values of the form.
+   *
+   * @return array
+   *   list of errors to be posted back to the form
+   */
+  public static function formRule($values) {
+    $errors = array();
+    //Process this function only when you get this variable
+    if ($values['allowRepeatConfigToSubmit'] == 1) {
+      $dayOfTheWeek = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
+      //Repeats
+      if (!CRM_Utils_Array::value('repetition_frequency_unit', $values)) {
+        $errors['repetition_frequency_unit'] = ts('This is a required field');
+      }
+      //Repeats every
+      if (!CRM_Utils_Array::value('repetition_frequency_interval', $values)) {
+        $errors['repetition_frequency_interval'] = ts('This is a required field');
+      }
+      //Ends
+      if (CRM_Utils_Array::value('ends', $values)) {
+        if ($values['ends'] == 1) {
+          if (empty($values['start_action_offset'])) {
+            $errors['start_action_offset'] = ts('This is a required field');
+          }
+          elseif ($values['start_action_offset'] > 30) {
+            $errors['start_action_offset'] = ts('Occurrences should be less than or equal to 30');
+          }
+        }
+        if ($values['ends'] == 2) {
+          if (CRM_Utils_Array::value('repeat_absolute_date', $values)) {
+            $entityStartDate = CRM_Utils_Date::processDate($values['repetition_start_date']);
+            $end = CRM_Utils_Date::processDate($values['repeat_absolute_date']);
+            if (($end < $entityStartDate) && ($end != 0)) {
+              $errors['repeat_absolute_date'] = ts('End date should be after current entity\'s start date');
+            }
+          }
+          else {
+            $errors['repeat_absolute_date'] = ts('This is a required field');
+          }
+        }
+      }
+      else {
+        $errors['ends'] = ts('This is a required field');
+      }
+
+      //Repeats BY
+      if (CRM_Utils_Array::value('repeats_by', $values)) {
+        if ($values['repeats_by'] == 1) {
+          if (CRM_Utils_Array::value('limit_to', $values)) {
+            if ($values['limit_to'] < 1 && $values['limit_to'] > 31) {
+              $errors['limit_to'] = ts('Invalid day of the month');
+            }
+          }
+          else {
+            $errors['limit_to'] = ts('Invalid day of the month');
+          }
+        }
+        if ($values['repeats_by'] == 2) {
+          if (CRM_Utils_Array::value('entity_status_1', $values)) {
+            $dayOfTheWeekNo = array(first, second, third, fourth, last);
+            if (!in_array($values['entity_status_1'], $dayOfTheWeekNo)) {
+              $errors['entity_status_1'] = ts('Invalid option');
+            }
+          }
+          else {
+            $errors['entity_status_1'] = ts('Invalid option');
+          }
+          if (CRM_Utils_Array::value('entity_status_2', $values)) {
+            if (!in_array($values['entity_status_2'], $dayOfTheWeek)) {
+              $errors['entity_status_2'] = ts('Invalid day name');
+            }
+          }
+          else {
+            $errors['entity_status_2'] = ts('Invalid day name');
+          }
+        }
+      }
+    }
+    return $errors;
+  }
+
+  /**
+   * Process the form submission
+   *
+   *
+   * @return void
+   */
+  public static function postProcess($params = array(), $type, $linkedEntities = array()) {
+    //Check entity_id not present in params take it from class variable
+    if (!CRM_Utils_Array::value('entity_id', $params)) {
+      $params['entity_id'] = self::$_entityId;
+    }
+    //Process this function only when you get this variable
+    if ($params['allowRepeatConfigToSubmit'] == 1) {
+      if (CRM_Utils_Array::value('entity_table', $params) && CRM_Utils_Array::value('entity_id', $params) && $type) {
+        $params['used_for'] = $type;
+        if (!CRM_Utils_Array::value('parent_entity_id', $params)) {
+          $params['parent_entity_id'] = self::$_parentEntityId;
+        }
+        if (CRM_Utils_Array::value('schedule_reminder_id', $params)) {
+          $params['id'] = $params['schedule_reminder_id'];
+        }
+        else {
+          $params['id'] = self::$_scheduleReminderID;
+        }
+
+        //Save post params to the schedule reminder table
+        $recurobj = new CRM_Core_BAO_RecurringEntity();
+        $dbParams = $recurobj->mapFormValuesToDB($params);
+
+        //Delete repeat configuration and rebuild
+        if (CRM_Utils_Array::value('id', $params)) {
+          CRM_Core_BAO_ActionSchedule::del($params['id']);
+          unset($params['id']);
+        }
+        $actionScheduleObj = CRM_Core_BAO_ActionSchedule::add($dbParams);
+
+        //exclude dates
+        $excludeDateList = array();
+        if (CRM_Utils_Array::value('copyExcludeDates', $params) && CRM_Utils_Array::value('parent_entity_id', $params) && $actionScheduleObj->entity_value) {
+          //Since we get comma separated values lets get them in array
+          $excludeDates = array();
+          $excludeDates = explode(",", $params['copyExcludeDates']);
+
+          //Check if there exists any values for this option group
+          $optionGroupIdExists = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup',
+            $type . '_repeat_exclude_dates_' . $params['parent_entity_id'],
+            'id',
+            'name'
+          );
+          if ($optionGroupIdExists) {
+            CRM_Core_BAO_OptionGroup::del($optionGroupIdExists);
+          }
+          $optionGroupParams = array(
+            'name' => $type . '_repeat_exclude_dates_' . $actionScheduleObj->entity_value,
+            'title' => $type . ' recursion',
+            'is_reserved' => 0,
+            'is_active' => 1,
+          );
+          $opGroup = CRM_Core_BAO_OptionGroup::add($optionGroupParams);
+          if ($opGroup->id) {
+            $oldWeight = 0;
+            $fieldValues = array('option_group_id' => $opGroup->id);
+            foreach ($excludeDates as $val) {
+              $optionGroupValue = array(
+                'option_group_id' => $opGroup->id,
+                'label' => CRM_Utils_Date::processDate($val),
+                'value' => CRM_Utils_Date::processDate($val),
+                'name' => $opGroup->name,
+                'description' => 'Used for recurring ' . $type,
+                'weight' => CRM_Utils_Weight::updateOtherWeights('CRM_Core_DAO_OptionValue', $oldWeight, CRM_Utils_Array::value('weight', $params), $fieldValues),
+                'is_active' => 1,
+              );
+              $excludeDateList[] = $optionGroupValue['value'];
+              CRM_Core_BAO_OptionValue::add($optionGroupValue);
+            }
+          }
+        }
+
+        //Set type for API
+        $apiEntityType = array();
+        $apiEntityType = explode("_", $type);
+        if (!empty($apiEntityType[1])) {
+          $apiType = $apiEntityType[1];
+        }
+        //Delete relations if any from recurring entity tables before inserting new relations for this entity id
+        if ($params['entity_id']) {
+          //If entity has any pre delete function, consider that first
+          if (CRM_Utils_Array::value('pre_delete_func', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]) &&
+            CRM_Utils_Array::value('helper_class', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']])
+          ) {
+            call_user_func(array(
+                CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['helper_class'],
+                call_user_func_array(CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['pre_delete_func'], array($params['entity_id'])),
+              )
+            );
+          }
+          //Ready to execute delete on entities if it has delete function set
+          if (CRM_Utils_Array::value('delete_func', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]) &&
+            CRM_Utils_Array::value('helper_class', CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']])
+          ) {
+            //Check if pre delete function has some ids to be deleted
+            if (!empty(CRM_Core_BAO_RecurringEntity::$_entitiesToBeDeleted)) {
+              foreach (CRM_Core_BAO_RecurringEntity::$_entitiesToBeDeleted as $eid) {
+                $result = civicrm_api3(
+                  ucfirst(strtolower($apiType)),
+                  CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['delete_func'],
+                  array(
+                    'sequential' => 1,
+                    'id' => $eid,
+                  )
+                );
+                if ($result['error']) {
+                  CRM_Core_Error::statusBounce('Error creating recurring list');
+                }
+              }
+            }
+            else {
+              $getRelatedEntities = CRM_Core_BAO_RecurringEntity::getEntitiesFor($params['entity_id'], $params['entity_table'], FALSE);
+              foreach ($getRelatedEntities as $key => $value) {
+                $result = civicrm_api3(
+                  ucfirst(strtolower($apiType)),
+                  CRM_Core_BAO_RecurringEntity::$_recurringEntityHelper[$params['entity_table']]['delete_func'],
+                  array(
+                    'sequential' => 1,
+                    'id' => $value['id'],
+                  )
+                );
+                if ($result['error']) {
+                  CRM_Core_Error::statusBounce('Error creating recurring list');
+                }
+              }
+            }
+          }
+
+          // find all entities from the recurring set. At this point we 'll get entities which were not deleted
+          // for e.g due to participants being present. We need to delete them from recurring tables anyway.
+          $pRepeatingEntities = CRM_Core_BAO_RecurringEntity::getEntitiesFor($params['entity_id'], $params['entity_table']);
+          foreach ($pRepeatingEntities as $val) {
+            CRM_Core_BAO_RecurringEntity::delEntity($val['id'], $val['table'], TRUE);
+          }
+        }
+
+        $recursion = new CRM_Core_BAO_RecurringEntity();
+        $recursion->dateColumns = $params['dateColumns'];
+        $recursion->scheduleId = $actionScheduleObj->id;
+
+        if (!empty($excludeDateList)) {
+          $recursion->excludeDates = $excludeDateList;
+          $recursion->excludeDateRangeColumns = $params['excludeDateRangeColumns'];
+        }
+        if (CRM_Utils_Array::value('intervalDateColumns', $params)) {
+          $recursion->intervalDateColumns = $params['intervalDateColumns'];
+        }
+        $recursion->entity_id = $params['entity_id'];
+        $recursion->entity_table = $params['entity_table'];
+        if (!empty($linkedEntities)) {
+          $recursion->linkedEntities = $linkedEntities;
+        }
+
+        $recurResult = $recursion->generate();
+
+        $status = ts('Repeat Configuration has been saved');
+        CRM_Core_Session::setStatus($status, ts('Saved'), 'success');
+      }
+    }
+  }
+
+  /**
+   * Return a descriptive name for the page, used in wizard header
+   *
+   * @return string
+   */
+  public function getTitle() {
+    return ts('Repeat Entity');
+  }
+
+}