function Streams_after_Q_objects() { $user = Users::loggedInUser(); if (!$user) { return; } $invite = Streams::$followedInvite; if (!$invite) { return; } $displayName = $user->displayName(); if ($displayName) { return; } $stream = new Streams_Stream(); $stream->publisherId = $invite->publisherId; $stream->name = $invite->streamName; if (!$stream->retrieve()) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'), 'streamName'); } // Prepare the complete invite dialog $invitingUser = Users_User::fetch($invite->invitingUserId); list($relations, $related) = Streams::related($user->id, $stream->publisherId, $stream->name, false); $params = array('displayName' => null, 'action' => 'Streams/basic', 'icon' => $user->iconUrl(), 'token' => $invite->token, 'user' => array('icon' => $invitingUser->iconUrl(), 'displayName' => $invitingUser->displayName(array('fullAccess' => true))), 'stream' => $stream->exportArray(), 'relations' => Db::exportArray($relations), 'related' => Db::exportArray($related)); $config = Streams_Stream::getConfigField($stream->type, 'invite', array()); $defaults = Q::ifset($config, 'dialog', array()); $tree = new Q_Tree($defaults); if ($tree->merge($params)) { $dialogData = $tree->getAll(); if ($dialogData) { Q_Response::setScriptData('Q.plugins.Streams.invite.dialog', $dialogData); Q_Response::addTemplate('Streams/invite/complete'); } } }
/** * Provide player content to view the members of category listing * Uses Streams/$type/category.php view (Streams/$streamType/category/get.php can be used for viewing the category * stream itself if type of category is $streamType/category) * and Streams::related to retrieve streams data * **/ function Streams_category_response_player() { $user = Users::loggedInUser(); $userId = $user ? $user->id : 0; // These are PK of the category! $publisherId = Streams::requestedPublisherId(true); $name = Streams::requestedName(true); // need to know publisher and type of the streams to list $streamType = Streams::requestedType(); if ($streamType) { $prefix = "{$streamType}/"; } $stream_publisherId = Q::expect('Streams', $streamType, 'publisher'); if (substr($name, -1) === '/') { throw new Q_Exception("Player cannot show listing for multiple categories", compact('publisherId', 'name')); } /* * Get shall return only streams which user is authorized to see. */ $categories = Streams::fetch($userId, $publisherId, $name); if (empty($categories)) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => compact('publisherId', 'name'))); } $category = reset($categories); // Are you authorized to see category content? if (!$category->testReadLevel('content')) { throw new Users_Exception_NotAuthorized(); } // get all the streams which are members of this category // as Streams::get verifies access rights, it's safe to show all streams' content list($relations, $streams) = Streams::related($userId, $publisherId, $name, true, array('prefix' => $prefix, 'skipAccess' => true)); Q::view("Stream/{$type}/category.php", compact('relations', 'streams', 'userId')); }
/** * This tool generates a category selector. * * @param array $options * An associative array of parameters, containing: * "publisherId" => Optional. publisherId of the stream to present. If "stream" parameter is empty * defaults to Streams::requestedPublisherId() * "name" => Optional. the name of the stream to present. If "stream" parameter is empty * defaults to Streams::requestedName() * "stream" => Optional. Object. The stream objects to show categories. */ function Streams_category_tool($options) { extract($options); $user = Users::loggedInUser(true); $userId = $user->id; // PK of stream to manage categories $publisherId = Streams::requestedPublisherId(true); $name = Streams::requestedName(true); $stream = Streams::get($userId, $publisherId, $name, null, true); if (!$stream) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: {$publisherId}, name: {$name}}")); } // activate tool frontend $default = array('publisherId' => $stream->publisherId, 'name' => $stream->name); $options = array_merge($default, $options); Q_Response::setToolOptions($options); // get the list of categories list($relations, $categories) = Streams::related($userId, $publisherId, $name, true); return Q::view("Streams/tool/category.php", compact('relations', 'categories', 'stream')); }
function Streams_related_response() { if (!Q_Request::slotName('relations') and !Q_Request::slotName('streams')) { return; } $user = Users::loggedInUser(); $asUserId = $user ? $user->id : ''; $publisherId = Streams::requestedPublisherId(true); $streamName = Streams::requestedName(true, 'original'); $isCategory = !empty($_REQUEST['isCategory']); $slotNames = Q_Request::slotNames(); $streams_requested = in_array('relatedStreams', $slotNames); $options = array('relationsOnly' => !$streams_requested, 'orderBy' => !empty($_REQUEST['ascending'])); if (isset($_REQUEST['limit'])) { $options['limit'] = $_REQUEST['limit']; } if (isset($_REQUEST['offset'])) { $options['offset'] = $_REQUEST['offset']; } if (isset($_REQUEST['min'])) { $options['min'] = $_REQUEST['min']; } if (isset($_REQUEST['max'])) { $options['max'] = $_REQUEST['max']; } if (isset($_REQUEST['type'])) { $options['type'] = $_REQUEST['type']; } if (isset($_REQUEST['prefix'])) { $options['prefix'] = $_REQUEST['prefix']; } $result = Streams::related($asUserId, $publisherId, $streamName, $isCategory, $options); if ($streams_requested) { $rel = Db::exportArray($result[0], array('numeric' => true)); } else { $rel = Db::exportArray($result, array('numeric' => true)); } if (!empty($_REQUEST['omitRedundantInfo'])) { if ($isCategory) { foreach ($rel as &$r) { unset($r['toPublisherId']); unset($r['toStreamName']); } } else { foreach ($rel as &$r) { unset($r['fromPublisherId']); unset($r['fromStreamName']); } } } Q_Response::setSlot('relations', $rel); if (!$streams_requested) { return; } $streams = $result[1]; $arr = Db::exportArray($streams, array('numeric' => true)); foreach ($arr as $k => $stream) { if (!$stream) { continue; } $s = $streams[$stream['name']]; $arr[$k]['access'] = array('readLevel' => $s->get('readLevel', $s->readLevel), 'writeLevel' => $s->get('writeLevel', $s->writeLevel), 'adminLevel' => $s->get('adminLevel', $s->adminLevel)); } Q_Response::setSlot('relatedStreams', $arr); $stream = $result[2]; if (is_array($stream)) { Q_Response::setSlot('streams', Db::exportArray($stream)); return; } else { if (is_object($stream)) { Q_Response::setSlot('stream', $stream->exportArray()); } else { Q_Response::setSlot('stream', false); } } if (!empty($_REQUEST['messages'])) { $max = -1; $limit = $_REQUEST['messages']; $messages = false; $type = isset($_REQUEST['messageType']) ? $_REQUEST['messageType'] : null; if ($stream->testReadLevel('messages')) { $messages = Db::exportArray($stream->getMessages(compact('type', 'max', 'limit'))); } Q_Response::setSlot('messages', $messages); } if (!empty($_REQUEST['participants'])) { $limit = $_REQUEST['participants']; $offset = -1; $participants = false; if ($stream->testReadLevel('participants')) { $participants = Db::exportArray($stream->getParticipants(compact('limit', 'offset'))); } Q_Response::setSlot('participants', $participants); } }
function Shipping_history_response_content($params) { // Do controller stuff here. Prepare variables // get "Shipping/shipments" stream $env = Shipping::getVars(); Q_Response::addStylesheet('css/ShipmentHistory.css'); Q_Response::addStylesheet('css/jquery.dropdown.css'); Q_Response::addScript('js/jquery.dropdown.js'); // run only once Q_Response::addScript('js/scheduled.js', ""); Q_Response::addScript('js/date.js', ""); // very first defaultState $defaultState = "pickup"; $shippingStates = array(); // get states from config $tmp = Q_Config::expect('Shipping', 'states'); foreach ($tmp as $shippingState) { // set default state if (isset($shippingState["default"]) && $shippingState["default"]) { $defaultState = $shippingState["type"]; } $shippingStates[$shippingState["type"]] = $shippingState["title"]; } // state from REQUEST have high priority, then defaultState from config $defaultState = isset($_REQUEST["type"]) ? $_REQUEST["type"] : $defaultState; // get next pickup date $streamsRes = Streams::related($env->communityId, $env->communityId, $env->shipmentsStreamName, true, array("type" => "pickup")); if (!count($streamsRes[1])) { $minDate = false; } else { $dateNow = new DateTime("now"); //$minDate = new DateTime((date("Y") + 1).'-'.date("m").'-'.date("d")); $maxDate = $minDate = false; foreach ($streamsRes[1] as $stream) { // skip stream if collectInstructions empty if (empty($stream->fields["collectInstructions"])) { continue; } $exportDate = json_decode($stream->fields["collectInstructions"]); // skip stream if $exportDate not an object if (json_last_error() !== JSON_ERROR_NONE || !is_object($exportDate)) { continue; } // if exportDate or collectTimeFrom or collectTimeTo empty - continue if (!property_exists($exportDate, "exportDate") || !property_exists($exportDate, "collectTimeFrom") || !property_exists($exportDate, "collectTimeTo")) { continue; } $startDate = DateTime::createFromFormat("Y-m-d G:i", $exportDate->exportDate . ' ' . $exportDate->collectTimeFrom); if ($startDate > $dateNow) { if (!$minDate || is_a($minDate, "DateTime") && $startDate < $minDate) { $minDate = $startDate; $maxDate = DateTime::createFromFormat("Y-m-d G:i", $exportDate->exportDate . ' ' . $exportDate->collectTimeTo); } } } if (is_a($minDate, "DateTime") && is_a($maxDate, "DateTime")) { $minDate = $minDate->format("l, j M Y") . " from " . $minDate->format("ga"); $minDate .= " to " . $maxDate->format("ga"); } else { $minDate = false; } } // collect carriers $shippingCarriers = array_keys(Q_Config::expect('Shipping', 'carriers')); $shippingCarriers = array_combine($shippingCarriers, $shippingCarriers); array_unshift($shippingCarriers, 'All'); //echo $minDate->format("l, j M Y")." from ".$minDate->format("ga")." to ".$maxDate->format("ga"); exit; return Q::view('Shipping/content/history.php', compact('env', 'shippingStates', 'defaultState', "minDate", "shippingCarriers")); }
/** * Fetch all the streams which are related to, or from, this stream. * @method related * @static * @param {string} $asUserId * The user who is fetching * @param {string} $publisherId * An array of criteria that includes either * @param {string} $toStreamName * The name of the category * @param {mixed} $isCategory * If false, returns the categories that this stream is related to. * If true, returns all the streams this related to this category. * If a string, returns all the streams related to this category with names prefixed by this string. * @param {array} $options=array() * 'limit' => number of records to fetch * 'offset' => offset to start * 'orderBy' => defaults to false, which means order by descending weight * 'type' => if specified, this filters the type of the relation * 'prefix' => if specified, this filters by the prefix of the related streams * 'where' => you can also specify any extra conditions here * 'extra' => An array of any extra options to pass to Streams::fetch when fetching streams * 'relationsOnly' => If true, returns only the relations to/from stream, doesn't fetch the streams. * Useful if publisher id of relation objects is not the same as provided by publisherId. * 'streamsOnly' => If true, returns only the streams related to/from stream, doesn't return the relations. * Useful for shorthand in while( ) statements. * 'streamFields' => If specified, fetches only the fields listed here for any streams * 'skipFields' => Optional array of field names. If specified, skips these fields when fetching streams * @return {array} * Returns array($relations, $relatedStreams, $this) */ function related($asUserId, $isCategory = true, $options = array()) { return Streams::related($asUserId, $this->publisherId, $this->name, $isCategory, $options); }
/** * Closes a stream, which prevents anyone from posting messages to it * unless they have WRITE_LEVEL >= "close", as well as attempting to remove * all relations to other streams. A "cron job" can later go and delete * closed streams. The reason you should avoid deleting streams right away * is that other subscribers may still want to receive the last messages * posted to the stream. * @method close * @param {string} $asUserId The id of the user who would be closing the stream * @param {string} $publisherId The id of the user publishing the stream * @param {string} $streamName The name of the stream * @param {array} [$options=array()] Can include "skipAccess" * @static */ static function close($asUserId, $publisherId, $streamName, $options = array()) { $stream = new Streams_Stream(); $stream->publisherId = $publisherId; $stream->name = $streamName; if (!$stream->retrieve()) { throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "{publisherId: '{$publisherId}', name: '{$streamName}'}")); } // Authorization check if (empty($options['skipAccess'])) { if ($asUserId !== $publisherId) { $stream->calculateAccess($asUserId); if (!$stream->testWriteLevel('close')) { throw new Users_Exception_NotAuthorized(); } } } // Clean up relations from other streams to this category list($relations, $related) = Streams::related($asUserId, $stream->publisherId, $stream->name, true); foreach ($relations as $r) { try { Streams::unrelate($asUserId, $r->fromPublisherId, $r->fromStreamName, $r->type, $stream->publisherId, $stream->name); } catch (Exception $e) { } } // Clean up relations from this stream to categories list($relations, $related) = Streams::related($asUserId, $stream->publisherId, $stream->name, false); foreach ($relations as $r) { try { Streams::unrelate($asUserId, $r->toPublisherId, $r->toStreamName, $r->type, $stream->publisherId, $stream->name); } catch (Exception $e) { } } $result = false; try { $db = $stream->db(); $stream->closedTime = $closedTime = $db->toDateTime($db->getCurrentTimestamp()); if ($stream->save()) { $stream->post($asUserId, array('type' => 'Streams/closed', 'content' => '', 'instructions' => compact('closedTime')), true); $result = true; } } catch (Exception $e) { throw $e; } return $result; }
function Shipping_invoice_response_content($params) { $publisherId = Users::communityId(); $streamName = 'Shipping/shipment/' . Q_Request::uri()->shipmentStreamName; $stream = Streams::fetchOne($publisherId, $publisherId, $streamName); $relation = Shipping::getShipmentRelation($stream); if (!$stream->testReadLevel('see')) { throw new Users_Exception_NotAuthorized(); } $carrier = json_decode($stream->carrier) ?: new StdClass(); // check if related invoices exists $invoices = Streams::related($stream->publisherId, $stream->publisherId, $stream->name, true, array("type" => "invoice")); $invoicesCount = count($invoices[1]); if ($invoicesCount) { $invoice = array_shift($invoices[1]); // for UPS fix PDF invoice to use tracking id in Waybill Number field if ($carrier->name == "UPS") { Shipping_Carrier_UPS::fixInvoice(APP_DIR . "/web/" . $invoice->content, $stream); exit; } header("location: " . Q_Request::baseUrl() . '/' . $invoice->content); exit; } //---------------------------------- // check if airwaybill bar code exist $carrier->AWBBarCode = false; $barCodes = Streams::related($stream->publisherId, $stream->publisherId, $stream->name, true, array("type" => "AWBBarCode")); $barCodesCount = count($barCodes[1]); if ($barCodesCount) { $barCode = array_shift($barCodes[1]); $carrier->AWBBarCode = Q_Request::baseUrl() . '/' . $barCode->content; } /* $carrier = json_decode($stream->fields['carrier']); if($carrier->name == "TNT"){ header ("Content-Type:text/xml"); echo $stream->fields['carrierInvoice']; exit; }*/ $addressReceiver = json_decode($stream->receiver) ?: new StdClass(); $addressReceiver->street = implode("<br>", Shipping_Carrier::addAddressLine($addressReceiver)); $addressFrom = json_decode($stream->origin) ?: new StdClass(); $addressFrom->street = implode("<br>", Shipping_Carrier::addAddressLine($addressFrom)); $addressTo = json_decode($stream->destination) ?: new StdClass(); $addressTo->street = implode("<br>", Shipping_Carrier::addAddressLine($addressTo)); $packages = json_decode($stream->packages) ?: new StdClass(); $products = json_decode($stream->products) ?: new StdClass(); $products->packages = Q::ifset($products, 'packages', array()); $products->currency = Q::ifset($products, 'currency', ''); if (!$carrier->name) { throw new exception("Carrier name empty!"); } if (!array_key_exists($carrier->name, Q_Config::expect('Shipping', 'carriers'))) { throw new exception("Unexpected carrier name " . $carrier->name . "!"); } $carrier->trackingId = Q::ifset($carrier, 'trackingId', ''); //$carrier->shipmentId = Q::ifset($carrier, 'waybillNumber', ''); $invoiceOptions = json_decode($stream->invoiceOptions) ?: new StdClass(); $invoiceOptions->invoiceNumber = Q::ifset($invoiceOptions, 'invoiceNumber', ''); $invoiceOptions->purchaseOrderNo = Q::ifset($invoiceOptions, 'purchaseOrderNo', ''); $invoiceOptions->reasonForExport = Q::ifset($invoiceOptions, 'reasonForExport', ''); $invoiceOptions->termsOfDelivery = Q::ifset($invoiceOptions, 'termsOfDelivery', ''); // normalize termsOfDelivery if ($invoiceOptions->termsOfDelivery) { $termsOfDelivery = Q_Config::expect('Shipping', "options", "termsOfDelivery"); if (array_key_exists($invoiceOptions->termsOfDelivery, $termsOfDelivery)) { $invoiceOptions->termsOfDelivery = $termsOfDelivery[$invoiceOptions->termsOfDelivery]["name"]; } } $invoiceOptions->ftrExemptions = Q::ifset($invoiceOptions, 'ftrExemptions', ''); $collectInstructions = json_decode($stream->collectInstructions) ?: new StdClass(); $collectInstructions->exportDate = Q::ifset($collectInstructions, 'exportDate', ''); Q_Response::addStylesheet('css/ShipmentInvoice.css'); Q_Response::addStylesheet('css/ShipmentInvoice' . $carrier->name . '.css'); //Q_Response::addStylesheet('js/jquery-editable/jquery-editable/css/jquery-editable.css'); //Q_Response::addScript('js/jquery-editable/jquery-editable/js/jquery-editable-poshytip.js'); //Q_Response::addScriptLine("$.fn.editable.defaults.mode = 'inline';"); return Q::view('Shipping/content/invoice' . $carrier->name . '.php', compact('addressFrom', 'addressTo', 'addressReceiver', 'packages', 'products', 'carrier', 'invoiceOptions', 'collectInstructions', 'streamName', 'relation')); }
function Shipping_label_response_content($params) { $streamName = Q_Request::uri()->shipmentStreamName; $publisherId = Users::communityId(); $stream = Streams::fetchOne($publisherId, $publisherId, 'Shipping/shipment/' . $streamName); if (!$stream->testReadLevel('see')) { throw new Users_Exception_NotAuthorized(); } $carrier = json_decode($stream->fields['carrier']) ?: new StdClass(); if (!is_object($carrier)) { throw new exception("carrier is not an object!"); } // TNT carrier if ($carrier->name == "TNT") { $xml = new XMLReader(); // check if XML valid if (!$xml->xml($stream->fields['carrierLabel'], NULL, LIBXML_DTDVALID)) { die("XML not valid"); } // add back button $stream->fields['carrierLabel'] = preg_replace("/<CONSIGNMENTBATCH>/", "<CONSIGNMENTBATCH>\n<ISWEBVIEW>" . Q_Request::isWebView() . "</ISWEBVIEW>", $stream->fields['carrierLabel']); // add FTR Exemptions $invoice = json_decode($stream->invoiceOptions) ?: new StdClass(); $stream->fields['carrierLabel'] = preg_replace("/<CONSIGNMENTBATCH>/", "<CONSIGNMENTBATCH>\n<FTR>" . $invoice->ftrExemptions . "</FTR>", $stream->fields['carrierLabel']); header("Content-Type:text/xml"); echo $stream->fields['carrierLabel']; exit; } elseif (in_array($carrier->name, array("UPS", "FEDEX"))) { $labels = Streams::related($stream->publisherId, $stream->publisherId, $stream->name, true, array("type" => "label")); $orient = Q_Config::expect('Shipping', 'labelsOption', 'orient'); $perPage = (int) Q_Config::expect('Shipping', 'labelsOption', 'perPage'); // angle label rotate 90 or -90 $angle = 1; // for UPS -90, for other 90 if ($carrier->name == "UPS") { $angle = -1; } // include labels size calculation for all labels Q_Response::addScript('js/labels.js'); Q_Response::addStylesheet('css/ShipmentLabels.css'); if ($orient == "vertical") { Q_Response::addStylesheet('css/ShipmentLabelsVertical.css'); } return Q::view('Shipping/content/imgLabels.php', compact('labels', 'perPage', 'angle')); } elseif ($carrier->name == "DHL") { $labels = Streams::related($stream->publisherId, $stream->publisherId, $stream->name, true, array("type" => "label")); $labelsCount = count($labels[1]); if ($labelsCount) { $label = array_shift($labels[1]); Shipping_Carrier_DHL::fixLabels(APP_DIR . "/web/" . $label->content, $stream); exit; //header("location: ".Q_Request::baseUrl().'/'.$label->content); //exit; } } $title = $stream->fields['title']; $addressFrom = json_decode($stream->fields['origin']); $addressTo = json_decode($stream->fields['destination']); $packages = json_decode($stream->fields['packages']); //$carrier = json_decode($stream->fields['carrier']); $invoiceOptions = json_decode($stream->fields['invoiceOptions']); $addressFrom = ($addressFrom->name ? $addressFrom->name . "<br>" : '') . $addressFrom->street . ($addressFrom->unit ? ' ' . $addressFrom->unit : '') . "<br>" . $addressFrom->city . ' ' . $addressFrom->zipcode . "<br>" . $addressFrom->country; $addressTo = ($addressTo->name ? $addressTo->name . "<br>" : '') . $addressTo->street . ($addressTo->unit ? ' ' . $addressTo->unit : '') . "<br>" . "<span class='city'>" . $addressTo->city . ' ' . $addressTo->zipcode . "</span><br>" . $addressTo->country; $exportDate = $invoiceOptions->exportDate; $class = "Shipping_Carrier_" . strtoupper($carrier->name); $labels = $class::labels($addressFrom, $addressTo, $packages, $carrier, $exportDate); echo <<<EOT \t<!DOCTYPE html> \t<html> \t<head> \t\t<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> \t\t<title>Labels for {$title}</title> \t</head> \t<body> \t{$labels} \t</body> </html> EOT; exit; }
/** * Get (if exist) or create shipment stream with type=describing for current user * @method shipment * @static * @return Object */ static function shipment() { $env = self::getVars(); // Collect streams for shipments. Relations: "describing", "scheduled", "confirmed", "shipping", "canceled", "returned" $streamsRes = Streams::related($env->userId, $env->communityId, $env->shipmentsStreamName, true, array("type" => "describing")); // if stream exists - return one if ($streamsRes[1]) { return reset($streamsRes[1]); } // if no streams with relation "describing" - create this stream // get last scheduled shippment stream $streamsScheduled = self::getRealShipments(); // find most new stream processed (not describing) $lastScheduled = false; foreach ($streamsScheduled[0] as $streamScheduled) { if (!$lastScheduled) { $lastScheduled = $streamScheduled; continue; } if ($streamScheduled->fields["insertedTime"] > $lastScheduled->fields["insertedTime"]) { $lastScheduled = $streamScheduled; } } // set Stream object instead of related object if ($lastScheduled) { $lastScheduled = $streamsScheduled[1][$lastScheduled->fields["fromStreamName"]]; $lastCarrier = json_decode($lastScheduled->fields["carrier"]); } // default carrier if no scheduled shippments if (!isset($lastCarrier) || !is_object($lastCarrier)) { $lastCarrier = json_decode("{name: 'TNT'}"); } return Streams::create($env->communityId, $env->communityId, 'Shipping/shipment', array("readLevel" => Streams::$READ_LEVEL['messages'], "writeLevel" => Streams::$WRITE_LEVEL['edit'], "skipAccess" => true, 'attributes' => '{"carrier":"' . $lastCarrier->name . '"}', 'title' => ''), array('publisherId' => $env->communityId, 'streamName' => $env->shipmentsStreamName, 'type' => 'describing', 'weight' => time())); }