/** * Perform client services-related periodic tasks */ public function hookPeriodicTask(&$pa_params) { $t_log = new Eventlog(); $o_db = new Db(); if (!(bool) $this->opo_config->get('enable_client_services')) { return true; } // Find any orders with status PROCESSED_AWAITING_MEDIA_ACCESS and fetch media $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_MEDIA_ACCESS'\n\t\t\t"); // // Set up HTTP client for REST calls // if ($this->opo_client_services_config->get('remote_media_base_url')) { $vs_base_url = $this->opo_client_services_config->get('remote_media_base_url'); $o_client = new RestClient($vs_base_url . "/service.php/iteminfo/ItemInfo/rest"); try { $o_res = $o_client->auth($this->opo_client_services_config->get('remote_media_username'), $this->opo_client_services_config->get('remote_media_password'))->get(); if (!$o_res->isSuccess()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not authenticate to remote system %1', $vs_base_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); } while ($qr_orders->nextRow()) { $t_order = new ca_commerce_orders($qr_orders->get('order_id')); $vb_download_errors = false; if ($t_order->getPrimaryKey() && sizeof($va_missing_media = $t_order->itemsMissingDownloadableMedia())) { $va_missing_media_representation_ids = $t_order->itemsMissingDownloadableMedia('original', array('returnRepresentationIDs' => true)); foreach ($va_missing_media as $vn_object_id => $va_representation_md5s) { foreach ($va_representation_md5s as $vn_i => $vs_representation_md5) { $o_xml = $o_client->getObjectRepresentationURLByMD5($vs_representation_md5, 'original')->get(); $vs_url = (string) $o_xml->getObjectRepresentationURLByMD5->original; if (!$vs_url) { continue; } // media no longer exists // fetch the file $t_rep = new ca_object_representations($va_missing_media_representation_ids[$vn_object_id][$vn_i]); if ($t_rep->getPrimaryKey() && ($vs_target_path = $t_rep->getMediaPath('media', 'original'))) { if ($r_source = fopen($vs_url, "rb")) { if ($r_target = fopen($vs_target_path, "wb")) { while (feof($r_source) === false) { fwrite($r_target, fread($r_source, 1024 * 8), 1024 * 8); } fclose($r_target); } else { $vb_download_errors = true; $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open target path %1', $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); } fclose($r_source); } else { $vb_download_errors = true; $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Could not open download URL "%1"', $vs_url), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); } // verify the file was downloaded correctly if (($vs_target_md5 = md5_file($vs_target_path)) !== $vs_representation_md5) { unlink($vs_target_path); $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Media file %1 failed to be downloaded from url "%2"; checksums differ: %3/%4', $vs_target_path, $vs_url, $vs_representation_md5, $vs_target_md5), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); $vb_download_errors = true; } } else { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Invalid representation_id "%1" or target path "%2"', $vn_representation_id, $vs_representation_md5, $vs_target_path), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); $vb_download_errors = true; } } } } if (!$vb_download_errors) { $t_order->setMode(ACCESS_WRITE); $t_order->set('order_status', 'PROCESSED'); $t_order->update(); if ($t_order->numErrors()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_MEDIA_ACCESS failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); } } } } catch (Exception $e) { // noop } } // Find any orders with status PROCESSED_AWAITING_DIGITIZATION where all media are now present $qr_orders = $o_db->query("\n\t\t\t\tSELECT order_id\n\t\t\t\tFROM ca_commerce_orders\n\t\t\t\tWHERE\n\t\t\t\t\torder_status = 'PROCESSED_AWAITING_DIGITIZATION'\n\t\t\t"); while ($qr_orders->nextRow()) { $t_order = new ca_commerce_orders($qr_orders->get('order_id')); if ($t_order->getPrimaryKey() && !sizeof($t_order->itemsWithNoDownloadableMedia())) { $t_order->setMode(ACCESS_WRITE); $t_order->set('order_status', 'PROCESSED'); $t_order->update(); if ($t_order->numErrors()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to PROCESSED from PROCESSED_AWAITING_DIGITIZATION failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); } } } // Find orders paid/shipped more than X days ago and mark them as "COMPLETED" $vn_days = (int) $this->opo_client_services_config->get('completed_order_age_threshold'); if ($vn_days > 1) { $vn_threshold = (int) (time() - $vn_days * 24 * 60 * 60); $qr_orders = $o_db->query("\n\t\t\t\t\tSELECT order_id\n\t\t\t\t\tFROM ca_commerce_orders\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(order_status = 'PROCESSED') \n\t\t\t\t\t\tAND \n\t\t\t\t\t\t((payment_received_on > 0) AND (payment_received_on < ?))\n\t\t\t\t\t\tAND \n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t(shipping_date IS NULL AND shipped_on_date IS NULL)\n\t\t\t\t\t\t\tOR\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t(shipped_on_date > 0) AND (shipped_on_date < ?)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t", $vn_threshold, $vn_threshold); while ($qr_orders->nextRow()) { $t_order = new ca_commerce_orders($qr_orders->get('order_id')); if ($t_order->getPrimaryKey()) { $t_order->setMode(ACCESS_WRITE); $t_order->set('order_status', 'COMPLETED'); $t_order->update(); if ($t_order->numErrors()) { $t_log->log(array('CODE' => 'ERR', 'MESSAGE' => _t('Change of order status to COMPLETED from PROCESSED failed for order_id %1: %2', $t_order->getPrimaryKey(), join('; ', $t_order->getErrors())), 'SOURCE' => 'clientServicesPlugin->hookPeriodicTask')); } } } } return true; }
public function RecordRepresentationSelection() { $pn_item_id = $this->request->getParameter('item_id', pInteger); $pn_representation_id = $this->request->getParameter('representation_id', pInteger); $pn_selected = $this->request->getParameter('selected', pInteger); $va_errors = array(); $t_order_item = new ca_commerce_order_items($pn_item_id); if (!$t_order_item->getPrimaryKey()) { $va_errors[] = _t("Invalid set item"); } if (!sizeof($va_errors)) { $t_order = new ca_commerce_orders($t_order_item->get('order_id')); if (!$t_order->getPrimaryKey()) { $va_errors[] = _t("Invalid order"); } if (!sizeof($va_errors)) { if ((bool) $pn_selected) { $t_order_item->addRepresentations(array($pn_representation_id)); } else { $t_order_item->removeRepresentations(array($pn_representation_id)); } $va_errors = $t_order_item->getErrors(); } } $this->view->setVar("errors", $va_errors); $this->view->setVar('representation_id', $pn_representation_id); $this->view->setVar('item_id', $pn_item_id); $this->render("ajax_select_representation_json.php"); }
/** * */ public function Download() { $pn_item_id = $this->request->getParameter('item_id', pInteger); $t_item = new ca_commerce_order_items($pn_item_id); $t_order = new ca_commerce_orders($t_item->get('order_id')); $t_transaction = new ca_commerce_transactions($t_order->get('transaction_id')); $o_media = new Media(); if ($t_item->getPrimaryKey() && $t_order->getPrimaryKey()) { // Is the order paid for... if (!in_array($t_order->get('order_status'), array('PROCESSED', 'PROCESSED_AWAITING_DIGITIZATION', 'COMPLETED'))) { $this->notification->addNotification(_t("This order must be processed before you can download items"), __NOTIFICATION_TYPE_ERROR__); $this->Index(); return; } // ... and accessible by this user? if ($t_transaction->get('user_id') != $this->request->getUserID()) { $this->notification->addNotification(_t("You may not download this item"), __NOTIFICATION_TYPE_ERROR__); $this->Index(); return; } // Is this item downloadable? if ($t_item->get('fullfillment_method') != 'DOWNLOAD') { $this->notification->addNotification(_t("This item cannot be downloaded"), __NOTIFICATION_TYPE_ERROR__); $this->Index(); return; } // Which reps, and what versions? $t_object = new ca_objects($t_item->get('object_id')); $va_services_list = array(); if (is_array($va_service_groups = $this->opo_client_services_config->getAssoc("service_groups"))) { foreach ($va_service_groups as $vs_group => $va_services_in_group) { foreach ($va_services_in_group['services'] as $vs_service => $va_service_info) { $va_services_list[$vs_service] = $va_service_info; } } } if (!($vs_version = $va_services_list[$t_item->get('service')]['download_version'])) { $vs_version = 'small'; } $va_reps = $t_object->getRepresentations(array($vs_version)); $va_reps_to_download = $t_item->getRepresentationIDs(); $o_zip = new ZipFile(); $va_files = array(); $vn_size = 0; foreach ($va_reps as $va_rep) { if (!isset($va_reps_to_download[$va_rep['representation_id']]) || !$va_reps_to_download[$va_rep['representation_id']]) { continue; } $va_tmp = explode('.', $va_rep['paths'][$vs_version]); $vs_ext = array_pop($va_tmp); if ($va_rep['original_filename']) { $va_tmp2 = explode(".", $va_rep['original_filename']); if (sizeof($va_tmp2) > 1) { array_pop($va_tmp2); } $vs_filename = join(".", $va_tmp2) . ".{$vs_ext}"; } else { $vs_filename = $t_object->get('idno') . "_" . $va_rep['representation_id'] . ".{$vs_ext}"; } $vn_size += $va_files[$va_rep['paths'][$vs_version]] = filesize($va_rep['paths'][$vs_version]); $o_zip->addFile($va_rep['paths'][$vs_version], $vs_filename, 0, array('compression' => 0)); } $this->view->setVar('zip', $o_zip); $this->view->setVar('version_download_name', date('dmY', $t_order->get('created_on', array('GET_DIRECT_DATE' => true))) . '-' . $t_order->getPrimaryKey()); // Log fulfillment $t_item->logFulfillmentEvent('DOWNLOAD', array('ip_addr' => $_SERVER['REMOTE_ADDR'], 'user_id' => $this->request->getUserID(), 'datetime' => time(), 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'files' => $va_files, 'size' => $vn_size, 'representation_ids' => $va_reps_to_download)); return $this->render('Account/download_binary.php'); } $this->notification->addNotification(_t("You may not download this"), __NOTIFICATION_TYPE_ERROR__); $this->Index(); return; }