/** * takes an associative array and creates a cancellation object * * the function extract all the params it needs to initialize the create a * resource object. the params array could contain additional unused name/value * pairs * * @param array $params (reference ) an assoc array of name/value pairs * @param array $ids the array that holds all the db ids * * @return object CRM_Booking_BAO_Cancellation object * @access public * @static */ static function create(&$values) { $bookingID = CRM_Utils_Array::value('booking_id', $values); if (!$bookingID) { return; } else { $transaction = new CRM_Core_Transaction(); try { $params = array('option_group_name' => CRM_Booking_Utils_Constants::OPTION_BOOKING_STATUS, 'name' => CRM_Booking_Utils_Constants::OPTION_VALUE_CANCELLED); $result = civicrm_api3('OptionValue', 'get', $params); $params = array(); $params['id'] = $bookingID; $params['status_id'] = CRM_Utils_Array::value('value', CRM_Utils_Array::value($result['id'], $result['values'])); $booking = CRM_Booking_BAO_Booking::create($params); $params = array(); $params['booking_id'] = $bookingID; $percentage = CRM_Utils_Array::value('cancellation_percentage', $values); $bookingTotal = CRM_Utils_Array::value('booking_total', $values); $cancellationFee = $bookingTotal * $percentage / 100; $additionalCharge = CRM_Utils_Array::value('additional_charge', $values); if (is_numeric($additionalCharge)) { $cancellationFee += $additionalCharge; $params['additional_fee'] = $additionalCharge; } $params['cancellation_date'] = CRM_Utils_Date::processDate(CRM_Utils_Array::value('cancellation_date', $values)); $params['comment'] = CRM_Utils_Array::value('comment', $values); $params['cancellation_fee'] = $cancellationFee; self::add($params); $slots = CRM_Booking_BAO_Slot::getBookingSlot($bookingID); foreach ($slots as $slotId => $slots) { $subSlots = CRM_Booking_BAO_SubSlot::getSubSlotSlot($slotId); foreach ($subSlots as $subSlotId => $subSlot) { CRM_Booking_BAO_SubSlot::cancel($subSlotId); } CRM_Booking_BAO_Slot::cancel($slotId); } // return TRUE; } catch (Exception $e) { $transaction->rollback(); CRM_Core_Error::fatal($e->getMessage()); } } }
function run() { //get date value from url through get method $date = CRM_Utils_Request::retrieve('date', 'Positive', $this, FALSE, 0); //convert javascript.getTime() to PHP date format $date = date('m/d/Y', round($date / 1000)); //get resources information by selected date $from = CRM_Utils_Date::processDate($date); $resources = CRM_Booking_BAO_Slot::getSlotDetailsOrderByResourceBetweenDate($from, $from); $values = array(); //put resources result to values, being ready to display. $values['resources'] = $resources; //Convert date to compile with crmDate $values['dayview_select_date'] = DateTime::createFromFormat('m/d/Y', $date)->format('Y-m-d'); //assign variables for use in a template $this->assign($values); // Example: Set the page-title dynamically; alternatively, declare a static title in xml/Menu/*.xml CRM_Utils_System::setTitle(ts('DayViewPrint')); parent::run(); }
function postProcess() { $values = $this->exportValues(); $selectedDate = CRM_Utils_Array::value('dayview_select_date', $values); //get booking slots from selected date $from = CRM_Utils_Date::processDate($selectedDate); $resources = CRM_Booking_BAO_Slot::getSlotDetailsOrderByResourceBetweenDate($from, $from); //put resources result to values, being ready to display. $values['resources'] = $resources; if (empty($resources)) { //check empty result //Convert date to show on no match found view $values['dayview_select_date'] = DateTime::createFromFormat('m/d/Y', $selectedDate)->format('d/m/Y'); } else { //Convert date to compile with crmDate $values['dayview_select_date'] = DateTime::createFromFormat('m/d/Y', $selectedDate)->format('Y-m-d'); } //assign values to show on template $this->assign($values); //parent::postProcess(); }
/** * Get all amount of booking * * Remark: The total_amount has been deducted from discount amount. */ static function getBookingAmount($id) { if (!$id) { return; } $bookingAmount = array('resource_fees' => 0, 'sub_resource_fees' => 0, 'adhoc_charges_fees' => 0, 'discount_amount' => 0, 'total_amount' => 0); $params = array('id' => $id); self::retrieve($params, $booking); $bookingAmount['discount_amount'] = CRM_Utils_Array::value('discount_amount', $booking); $bookingAmount['total_amount'] = CRM_Utils_Array::value('total_amount', $booking); $slots = CRM_Booking_BAO_Slot::getBookingSlot($id); $subSlots = array(); foreach ($slots as $key => $slot) { $subSlotResult = CRM_Booking_BAO_SubSlot::getSubSlotSlot($slot['id']); foreach ($subSlotResult as $key => $subSlot) { $subSlots[$key] = $subSlot; } } $adhocCharges = CRM_Booking_BAO_AdhocCharges::getBookingAdhocCharges($id); $params = array('booking_id' => $id); CRM_Booking_BAO_Payment::retrieve($params, $payment); if (!empty($payment) && isset($payment['contribution_id'])) { // contribution exit so get all price from line item /* $params = array( 'version' => 3, 'id' => $payment['contribution_id'], ); $result = civicrm_api('Contribution', 'get', $params); $contribution = CRM_Utils_Array::value($payment['contribution_id'], $result['values'] ); $bookingAmount['total_amount'] = CRM_Utils_Array::value('total_amount', $contribution); */ foreach ($slots as $slotId => $slot) { $params = array('version' => 3, 'entity_id' => $slotId, 'entity_table' => 'civicrm_booking_slot'); $result = civicrm_api('LineItem', 'get', $params); $lineItem = CRM_Utils_Array::value($result['id'], $result['values']); $bookingAmount['resource_fees'] += CRM_Utils_Array::value('line_total', $lineItem); } foreach ($subSlots as $subSlotId => $subSlots) { $params = array('version' => 3, 'entity_id' => $subSlotId, 'entity_table' => 'civicrm_booking_sub_slot'); $result = civicrm_api('LineItem', 'get', $params); $lineItem = CRM_Utils_Array::value($result['id'], $result['values']); $bookingAmount['sub_resource_fees'] += CRM_Utils_Array::value('line_total', $lineItem); } foreach ($adhocCharges as $charges) { $params = array('version' => 3, 'entity_id' => CRM_Utils_Array::value('id', $charges), 'entity_table' => 'civicrm_booking_adhoc_charges'); $result = civicrm_api('LineItem', 'get', $params); $lineItem = CRM_Utils_Array::value($result['id'], $result['values']); $bookingAmount['adhoc_charges_fees'] += CRM_Utils_Array::value('line_total', $lineItem); } } else { foreach ($slots as $id => $slot) { $bookingAmount['resource_fees'] += CRM_Booking_BAO_Slot::calulatePrice(CRM_Utils_Array::value('config_id', $slot), CRM_Utils_Array::value('quantity', $slot)); } foreach ($subSlots as $id => $subSlot) { $bookingAmount['sub_resource_fees'] += CRM_Booking_BAO_Slot::calulatePrice(CRM_Utils_Array::value('config_id', $subSlot), CRM_Utils_Array::value('quantity', $subSlot)); } foreach ($adhocCharges as $charges) { $price = CRM_Core_DAO::getFieldValue('CRM_Booking_DAO_AdhocChargesItem', CRM_Utils_Array::value('item_id', $charges), 'price', 'id'); $bookingAmount['adhoc_charges_fees'] += $price * CRM_Utils_Array::value('quantity', $charges); } } return $bookingAmount; }
static function getSlots() { $config = CRM_Booking_BAO_BookingConfig::getConfig(); $bookedColour = CRM_Utils_Array::value('slot_booked_colour', $config); $provisionalColour = CRM_Utils_Array::value('slot_provisional_colour', $config); $booking = NULL; if (!empty($_GET['booking_id'])) { $bookingId = CRM_Utils_Type::escape($_GET['booking_id'], 'String'); } $timeshift = CRM_Utils_Type::escape($_GET['timeshift'], 'String'); $from = CRM_Utils_Type::escape($_GET['from'], 'String'); $to = CRM_Utils_Type::escape($_GET['to'], 'String'); $slots = array("data" => array()); $results = CRM_Booking_BAO_Slot::getSlotBetweenDate($from, $to); foreach ($results as $key => $slot) { if ($bookingId != CRM_Utils_Array::value('booking_id', $slot)) { //do not thing $params = array('id' => CRM_Utils_Array::value('booking_id', $slot)); CRM_Booking_BAO_Booking::retrieve($params, $booking); $bookingStatus = CRM_Utils_Array::value('status_id', $booking); $displayName = CRM_Contact_BAO_Contact::displayName(CRM_Utils_Array::value('primary_contact_id', $booking)); $data = array("id" => $key, "start_date" => CRM_Utils_Array::value('start', $slot), "end_date" => CRM_Utils_Array::value('end', $slot), "text" => CRM_Utils_Array::value('booking_id', $slot) . ' : ' . $displayName, "resource_id" => CRM_Utils_Array::value('resource_id', $slot), "configuration_id" => CRM_Utils_Array::value('config_id', $slot), "price" => CRM_Booking_BAO_Slot::calulatePrice($slot['config_id'], $slot['quantity']), "quantity" => CRM_Utils_Array::value('quantity', $slot), "note" => CRM_Utils_Array::value('note', $slot), "readonly" => true, "booking_id" => CRM_Utils_Array::value('booking_id', $slot)); if ($bookingStatus == 1) { //Provisional, TODO: Fixed to get the value from the name i.e provisional $data['color'] = $provisionalColour; } else { $data['color'] = $bookedColour; } array_push($slots['data'], $data); } } echo json_encode($slots); CRM_Utils_System::civiExit(); }
/** * Function to process the form * * @access public * * @return None */ public function postProcess() { CRM_Utils_System::flushCache(); $params = $this->exportValues(); if ($this->_action & CRM_Core_Action::DELETE) { CRM_Booking_BAO_Slot::delByResource($this->_id); CRM_Booking_BAO_Resource::del($this->_id); CRM_Core_Session::setStatus(ts('Selected resource has been deleted.'), ts('Record Deleted'), 'success'); } else { $params = $this->exportValues(); // If the is_active (enabled) checkbox is NOT set, it is NOT sent down in the form // The DAO definition for is_active has a default of '1' // So if not set it is by default ENABLED when in fact it should be DISABLED if (!isset($params['is_active'])) { $params['is_active'] = 0; } if ($this->_id) { $params['id'] = $this->_id; } $resource = CRM_Booking_BAO_Resource::create($params); CRM_Core_Session::setStatus(ts('The Record \'%1\' has been saved.', array(1 => $resource->label)), ts('Saved'), 'success'); } }
/** * Slot.Validate API * * @param array $params * @return array API result descriptor * @see civicrm_api3_create_success * @see civicrm_api3_create_error * @throws API_Exception */ function civicrm_api3_slot_validate($params) { $resources = $params['resources']; $isValid = TRUE; $errorResources = array(); $slot = array(); foreach ($resources as $key => $resource) { if (!CRM_Booking_BAO_Slot::isValid($resource)) { $errorResources[] = $resource; } //$slot[] = $resource; } /*$num = sizeof($slot); for($i=0; $i<=$num; $i++){ $currentSlot = $slot[$i]; for($j=$i; $j<=$num; $j++){ $testSlot = $slot[$j]; } }*/ if (!empty($errorResources)) { $isValid = FALSE; } return civicrm_api3_create_success(array('is_valid' => $isValid, 'error_resources' => $errorResources), $params, 'slot', 'validate'); }
function postProcess() { $bookingInfo = $this->exportValues(); $selectResource = $this->controller->exportValues('SelectResource'); $addSubResource = $this->controller->exportValues('AddSubResource'); $resourcesValue = json_decode($selectResource['resources'], true); $subResourcesValue = json_decode($addSubResource['sub_resources'], true); $subResources = $subResourcesValue['sub_resources']; //Build resources array for passing to Booking APIs $resources = array(); foreach ($resourcesValue as $key => $resource) { //Remove element that used in DTHMLX as we do not need them. unset($resource['id']); unset($resource['label']); unset($resource['text']); unset($resource['readonly']); $resource['start_date'] = $resource['start_date']; $resource['end_date'] = $resource['end_date']; $resource['sub_resources'] = array(); if (isset($subResources)) { foreach ($subResources as $subKey => $subResource) { if ($key == $subResource['parent_ref_id']) { $subResourceTmp['resource_id'] = $subResource['resource']['id']; $subResourceTmp['configuration_id'] = $subResource['configuration']['id']; $subResourceTmp['quantity'] = $subResource['quantity']; $subResourceTmp['time_required'] = $subResource['time_required']; $subResourceTmp['note'] = $subResource['note']; $subResourceTmp['price_estimate'] = $subResource['price_estimate']; array_push($resource['sub_resources'], $subResourceTmp); unset($subResources[$subKey]); } } } array_push($resources, $resource); } $adhocCharges = CRM_Utils_Array::value('adhoc_charges', $subResourcesValue); $booking = array(); if ($this->_id && $this->_action == CRM_Core_Action::UPDATE) { $booking['id'] = $this->_id; } $booking['primary_contact_id'] = CRM_Utils_Array::value('primary_contact_id', $bookingInfo); $booking['secondary_contact_id'] = CRM_Utils_Array::value('secondary_contact_id', $bookingInfo); $booking['po_number'] = CRM_Utils_Array::value('po_no', $bookingInfo); $booking['status_id'] = CRM_Utils_Array::value('booking_status', $bookingInfo); $booking['title'] = CRM_Utils_Array::value('title', $bookingInfo); $booking['description'] = CRM_Utils_Array::value('description', $bookingInfo); $booking['note'] = CRM_Utils_Array::value('note', $bookingInfo); $booking['booking_date'] = CRM_Utils_Date::processDate(CRM_Utils_Array::value('event_start_date', $bookingInfo), CRM_Utils_Array::value('event_start_date_time', $bookingInfo)); $booking['discount_amount'] = CRM_Utils_Array::value('discount_amount', $addSubResource); $booking['total_amount'] = CRM_Utils_Array::value('total_price', $addSubResource); $amountToFloat = floatval($booking['total_amount']); $booking['total_amount'] = round($amountToFloat, 2, PHP_ROUND_HALF_UP); //add adhoc charge $booking['adhoc_charges_note'] = CRM_Utils_Array::value('note', $adhocCharges); $booking['participants_estimate'] = CRM_Utils_Array::value('enp', $bookingInfo); $booking['participants_actual'] = CRM_Utils_Array::value('fnp', $bookingInfo); $now = date('YmdHis'); $session =& CRM_Core_Session::singleton(); $booking['created_by'] = $session->get('userID'); $booking['created_date'] = $now; $booking['updated_by'] = $session->get('userID'); $booking['updated_date'] = $now; //retrieve booking_start_date, booking_end_date from all slots $dates = array(); foreach ($resources as $key => $slot) { array_push($dates, CRM_Utils_Array::value('start_date', $slot)); array_push($dates, CRM_Utils_Array::value('end_date', $slot)); } sort($dates); $bookingStartDate = $dates[0]; $bookingEndDate = $dates[count($dates) - 1]; $booking['booking_start_date'] = CRM_Utils_Date::processDate($bookingStartDate); $booking['booking_end_date'] = CRM_Utils_Date::processDate($bookingEndDate); //make sure we create everything in one transaction, not too nice but it does the job $transaction = new CRM_Core_Transaction(); try { $result = civicrm_api3('Booking', 'Create', $booking); $bookingID = CRM_Utils_Array::value('id', $result); $booking = CRM_Utils_Array::value($bookingID, CRM_Utils_Array::value('values', $result)); $this->_id = $bookingID; //make sure we have the id on create mode $this->_values = $booking; //Now we process slots/subslots and adhoc charges if ($this->_action == CRM_Core_Action::UPDATE) { //booking id was passed from the form so we are on edit mode $currentSlots = CRM_Booking_BAO_Slot::getBookingSlot($bookingID); } $newSlotIds = array(); $newSubSlotIds = array(); foreach ($resources as $key => $resource) { $slot = array('booking_id' => $bookingID, 'config_id' => CRM_Utils_Array::value('configuration_id', $resource), 'start' => CRM_Utils_Date::processDate(CRM_Utils_Array::value('start_date', $resource)), 'end' => CRM_Utils_Date::processDate(CRM_Utils_Array::value('end_date', $resource)), 'resource_id' => CRM_Utils_Array::value('resource_id', $resource), 'quantity' => CRM_Utils_Array::value('quantity', $resource), 'note' => CRM_Utils_Array::value('note', $resource)); if ($this->_action == CRM_Core_Action::UPDATE) { list($isExist, $currentID) = CRM_Booking_BAO_Slot::findExistingSlot($slot, $currentSlots); if ($isExist) { $slot['id'] = $currentID; } } $slotResult = civicrm_api3('Slot', 'create', $slot); $slotID = CRM_Utils_Array::value('id', $slotResult); array_push($newSlotIds, $slotID); if ($this->_action == CRM_Core_Action::UPDATE) { $currentSubSlots = CRM_Booking_BAO_SubSlot::getSubSlotSlot($slotID); } $subResources = $resource['sub_resources']; foreach ($subResources as $subKey => $subResource) { $subSlot = array('resource_id' => CRM_Utils_Array::value('resource_id', $subResource), 'slot_id' => $slotID, 'config_id' => CRM_Utils_Array::value('configuration_id', $subResource), 'time_required' => CRM_Utils_Date::processDate(CRM_Utils_Array::value('time_required', $subResource)), 'quantity' => CRM_Utils_Array::value('quantity', $subResource), 'note' => CRM_Utils_Array::value('note', $subResource)); if ($this->_action == CRM_Core_Action::UPDATE) { list($isExist, $currentSubSlotId) = CRM_Booking_BAO_SubSlot::findExistingSubSlot($subSlot, $currentSubSlots); if ($isExist) { $subSlot['id'] = $currentSubSlotId; } } $subSlotResult = civicrm_api3('SubSlot', 'Create', $subSlot); $subSlotID = CRM_Utils_Array::value('id', $subSlotResult); array_push($newSubSlotIds, $subSlotID); } if ($this->_action == CRM_Core_Action::UPDATE) { //remove subslots that have been removed $subSlotsToBeRemoved = array(); foreach ($currentSubSlots as $key => $currentSubSlot) { if (!in_array($key, $newSubSlotIds)) { $subSlotsToBeRemoved[$key] = $currentSubSlot; } } if (!empty($subSlotsToBeRemoved)) { foreach ($subSlotsToBeRemoved as $key => $slot) { civicrm_api3('SubSlot', 'delete', array('id' => $key)); } } } } if ($this->_action == CRM_Core_Action::UPDATE) { //remove all slots that have been removed $slotsToBeRemoved = array(); foreach ($currentSlots as $key => $currentSlot) { if (!in_array($key, $newSlotIds)) { $slotsToBeRemoved[$key] = $currentSlot; } } if (!empty($slotsToBeRemoved)) { foreach ($slotsToBeRemoved as $key => $slot) { civicrm_api3('Slot', 'delete', array('id' => $key)); } } } if ($adhocCharges) { if ($this->_action == CRM_Core_Action::UPDATE) { $result = civicrm_api3('AdhocCharges', 'get', array('booking_id' => $bookingID, 'is_deleted' => 0)); $currentAdhocCharges = $result['values']; } // fixed bug of CVB-94 // Ad-hoc charges - cannot save if (!is_null(CRM_Utils_Array::value('items', $adhocCharges))) { $items = array_filter(CRM_Utils_Array::value('items', $adhocCharges)); $newAdhocChargesIds = array(); foreach ($items as $key => $item) { $params = array('booking_id' => $bookingID, 'item_id' => CRM_Utils_Array::value('item_id', $item), 'quantity' => CRM_Utils_Array::value('quantity', $item)); if ($this->_action == CRM_Core_Action::UPDATE) { list($isExist, $currentAdhocChargesId) = CRM_Booking_BAO_AdhocCharges::findExistingAdhocCharges($params, $currentAdhocCharges); if ($isExist) { $params['id'] = $currentAdhocChargesId; } } $result = civicrm_api3('AdhocCharges', 'create', $params); $adhocChargesId = CRM_Utils_Array::value('id', $result); array_push($newAdhocChargesIds, $adhocChargesId); } } if ($this->_action == CRM_Core_Action::UPDATE) { //remove adhoc charges that have been removed $adhocChargesToBeRemoved = array(); foreach ($currentAdhocCharges as $key => $adc) { if (!in_array($key, $newAdhocChargesIds)) { $adhocChargesToBeRemoved[$key] = $adc; } } if (!empty($adhocChargesToBeRemoved)) { foreach ($adhocChargesToBeRemoved as $key => $adc) { civicrm_api3('AdhocCharges', 'delete', array('id' => $key)); } } } } //End process parent::postProcess(); $cid = CRM_Utils_Array::value('primary_contact_id', $bookingInfo); // user context $url = CRM_Utils_System::url('civicrm/contact/view/booking', "reset=1&id={$bookingID}&cid={$cid}&action=view"); CRM_Core_Session::setStatus($booking['title'], ts('Saved'), 'success'); CRM_Utils_System::redirect($url); } catch (CiviCRM_API3_Exception $e) { $transaction->rollback(); CRM_Core_Error::fatal($e->getMessage()); } catch (Exception $e) { $transaction->rollback(); CRM_Core_Error::fatal($e->getMessage()); } }
/** * * * @return void * @author */ static function getSlotDetailsOrderByResourceBetweenDate($from, $to) { $slots = array(); $slotsResult = CRM_Booking_BAO_Slot::getSlotBetweenDate($from, $to); foreach ($slotsResult as $key => $slotItem) { //get booking detail $params = array('booking_id' => $slotItem['booking_id']); $bookingResult = civicrm_api3('Booking', 'get', $params); $bookingValues = CRM_Utils_Array::value('values', $bookingResult); foreach ($bookingValues as $k1 => $booking) { //set booking detail $slotItem['function_title'] = $booking['title']; $slotItem['note'] = isset($booking['note']) ? $booking['note'] : NULL; $slotItem['estimated_participant'] = isset($booking['participants_estimate']) ? $booking['participants_estimate'] : NULL; //get contacts detail if (isset($booking['primary_contact_id'])) { $paramsContact = array('contact_id' => $booking['primary_contact_id']); $contactResult = civicrm_api3('Contact', 'get', $paramsContact); $contactValue = CRM_Utils_Array::value('values', $contactResult); foreach ($contactValue as $k2 => $primaryContact) { //set primary contact $slotItem['primary_contact'] = $primaryContact['display_name']; } } if (isset($booking['secondary_contact_id'])) { $paramsContact = array('contact_id' => $booking['secondary_contact_id']); $contactResult = civicrm_api3('Contact', 'get', $paramsContact); $contactValue = CRM_Utils_Array::value('values', $contactResult); foreach ($contactValue as $k2 => $secondContact) { //set secondary contact $slotItem['secondary_contact'] = $secondContact['display_name']; } } } $slotItem['resource_config_label'] = CRM_Core_DAO::getFieldValue('CRM_Booking_DAO_ResourceConfigOption', $slotItem['config_id'], 'label', 'id'); //get resource config detail $slotItem['resource_label'] = CRM_Core_DAO::getFieldValue('CRM_Booking_DAO_Resource', $slotItem['resource_id'], 'label', 'id'); //get sub slot $subSlots = array(); $params = array('slot_id' => $slotItem['id'], 'entity_table' => 'civicrm_booking_sub_slot'); $subSlotResult = civicrm_api3('SubSlot', 'get', $params); $subSlotValues = CRM_Utils_Array::value('values', $subSlotResult); foreach ($subSlotValues as $k1 => $subSlotItem) { //set sub slot detail if ($subSlotItem['is_deleted'] == 0) { $subSlots[$k1]['sub_resource_label'] = CRM_Core_DAO::getFieldValue('CRM_Booking_DAO_Resource', $subSlotItem['resource_id'], 'label', 'id'); $subSlots[$k1]['sub_resource_config_label'] = CRM_Core_DAO::getFieldValue('CRM_Booking_DAO_ResourceConfigOption', $subSlotItem['config_id'], 'label', 'id'); $subSlots[$k1]['time_required'] = $subSlotItem['time_required']; $subSlots[$k1]['quantity'] = $subSlotItem['quantity']; $subSlots[$k1]['booking_id'] = $slotItem['booking_id']; $subSlots[$k1]['primary_contact'] = $slotItem['primary_contact']; $subSlots[$k1]['secondary_contact'] = isset($slotItem['secondary_contact']) ? $slotItem['secondary_contact'] : NULL; $subSlots[$k1]['note'] = isset($subSlotItem['note']) ? $subSlotItem['note'] : NULL; } } //final setting values $slotItem['sub_resources'] = !empty($subSlots) ? $subSlots : NULL; $slots[$key] = $slotItem; } //rearrange items by resource $orderResource = array(); foreach ($slots as $key => $slotItem) { //retrieve resource_labels $tempArray = array('id' => CRM_Utils_Array::value('resource_id', $slotItem), 'label' => CRM_Utils_Array::value('resource_label', $slotItem), 'slot' => array(), 'subslot' => array()); if (!array_search($tempArray, $orderResource)) { $orderResource[$key] = $tempArray; } } foreach ($orderResource as $key => $resItem) { foreach ($slots as $k1 => $slotItem) { if ($resItem['label'] == $slotItem['resource_label']) { $orderResource[$key]['slot'][] = $slotItem; if (!empty($slotItem['sub_resources'])) { $orderResource[$key]['subslot'][] = $slotItem['sub_resources']; } } } } return $orderResource; }