芝麻web文件管理V1.00
编辑当前文件:/home/mgatv524/public_html/avenida/lib/Entity/Campaign.php
. */ namespace Xibo\Entity; use Respect\Validation\Validator as v; use Xibo\Exception\InvalidArgumentException; use Xibo\Exception\NotFoundException; use Xibo\Exception\XiboException; use Xibo\Factory\DisplayFactory; use Xibo\Factory\LayoutFactory; use Xibo\Factory\PermissionFactory; use Xibo\Factory\ScheduleFactory; use Xibo\Factory\TagFactory; use Xibo\Service\LogServiceInterface; use Xibo\Storage\StorageServiceInterface; /** * Class Campaign * @package Xibo\Entity * * @SWG\Definition() */ class Campaign implements \JsonSerializable { use EntityTrait; /** * @SWG\Property(description="The Campaign Id") * @var int */ public $campaignId; /** * @SWG\Property(description="The userId of the User that owns this Campaign") * @var int */ public $ownerId; /** * @SWG\Property(description="The name of the Campaign") * @var string */ public $campaign; /** * @SWG\Property(description="A 0|1 flag to indicate whether this is a Layout specific Campaign or not.") * @var int */ public $isLayoutSpecific = 0; /** * @SWG\Property(description="The number of Layouts associated with this Campaign") * @var int */ public $numberLayouts; /** * @SWG\Property(description="The total duration of the campaign (sum of layout's durations)") * @var int */ public $totalDuration; public $tags = []; /** * @var Layout[] */ private $layouts = []; /** * @var Permission[] */ private $permissions = []; /** * @var Schedule[] */ private $events = []; // Private private $unassignTags = []; /** @var bool Have the Layout assignments changed? */ private $layoutAssignmentsChanged = false; /** * @var PermissionFactory */ private $permissionFactory; /** * @var LayoutFactory */ private $layoutFactory; /** * @var TagFactory */ private $tagFactory; /** * @var ScheduleFactory */ private $scheduleFactory; /** * @var DisplayFactory */ private $displayFactory; /** * Entity constructor. * @param StorageServiceInterface $store * @param LogServiceInterface $log * @param PermissionFactory $permissionFactory * @param ScheduleFactory $scheduleFactory * @param DisplayFactory $displayFactory * @param TagFactory $tagFactory */ public function __construct($store, $log, $permissionFactory, $scheduleFactory, $displayFactory, $tagFactory) { $this->setCommonDependencies($store, $log); $this->permissionFactory = $permissionFactory; $this->scheduleFactory = $scheduleFactory; $this->displayFactory = $displayFactory; $this->tagFactory = $tagFactory; } /** * Set Child Object Depencendies * must be set before calling Load with all objects * @param LayoutFactory $layoutFactory * @return $this */ public function setChildObjectDependencies($layoutFactory) { $this->layoutFactory = $layoutFactory; return $this; } /** * @return string */ public function __toString() { return sprintf('CampaignId %d, Campaign %s, LayoutSpecific %d', $this->campaignId, $this->campaign, $this->isLayoutSpecific); } /** * Get the Id * @return int */ public function getId() { return $this->campaignId; } /** * Get the OwnerId * @return int */ public function getOwnerId() { return $this->ownerId; } /** * Sets the Owner * @param int $ownerId */ public function setOwner($ownerId) { $this->ownerId = $ownerId; } /** * @param array $options * @throws \Xibo\Exception\NotFoundException */ public function load($options = []) { $options = array_merge([ 'loadPermissions' => true, 'loadLayouts' => true, 'loadTags' => true, 'loadEvents' => true ], $options); // If we are already loaded, then don't do it again if ($this->campaignId == null || $this->loaded) return; if ($this->layoutFactory == null) throw new \RuntimeException('Cannot load campaign with all objects without first calling setChildObjectDependencies'); // Permissions if ($options['loadPermissions']) $this->permissions = $this->permissionFactory->getByObjectId('Campaign', $this->campaignId); // Layouts if ($options['loadLayouts']) $this->layouts = $this->layoutFactory->getByCampaignId($this->campaignId, false); // Load all tags if ($options['loadTags']) $this->tags = $this->tagFactory->loadByCampaignId($this->campaignId); // Events if ($options['loadEvents']) $this->events = $this->scheduleFactory->getByCampaignId($this->campaignId); $this->loaded = true; } /** * @throws InvalidArgumentException */ public function validate() { if (!v::stringType()->notEmpty()->validate($this->campaign)) throw new InvalidArgumentException(__('Name cannot be empty'), 'name'); } /** * Does the campaign have the provided tag? * @param $searchTag * @return bool * @throws NotFoundException */ public function hasTag($searchTag) { $this->load(); foreach ($this->tags as $tag) { /* @var Tag $tag */ if ($tag->tag == $searchTag) return true; } return false; } /** * Assign Tag * @param Tag $tag * @return $this */ public function assignTag($tag) { $this->load(); if (!in_array($tag, $this->tags)) $this->tags[] = $tag; return $this; } /** * Unassign tag * @param Tag $tag * @return $this */ public function unassignTag($tag) { $this->tags = array_udiff($this->tags, [$tag], function($a, $b) { /* @var Tag $a */ /* @var Tag $b */ return $a->tagId - $b->tagId; }); return $this; } /** * @param array[Tag] $tags */ public function replaceTags($tags = []) { if (!is_array($this->tags) || count($this->tags) <= 0) $this->tags = $this->tagFactory->loadByCampaignId($this->campaignId); $this->unassignTags = array_udiff($this->tags, $tags, function($a, $b) { /* @var Tag $a */ /* @var Tag $b */ return $a->tagId - $b->tagId; }); $this->getLog()->debug('Tags to be removed: %s', json_encode($this->unassignTags)); // Replace the arrays $this->tags = $tags; $this->getLog()->debug('Tags remaining: %s', json_encode($this->tags)); } /** * Save this Campaign * @param array $options * @throws InvalidArgumentException */ public function save($options = []) { $options = array_merge([ 'validate' => true, 'notify' => true, 'collectNow' => true, 'saveTags' => true ], $options); $this->getLog()->debug('Saving ' . $this); if ($options['validate']) $this->validate(); if ($this->campaignId == null || $this->campaignId == 0) { $this->add(); $this->loaded = true; } else $this->update(); // Save the tags if (is_array($this->tags)) { foreach ($this->tags as $tag) { /* @var Tag $tag */ $this->getLog()->debug('Assigning tag ' . $tag->tag); $tag->assignCampaign($this->campaignId); $tag->save(); } } // Remove unwanted ones if (is_array($this->unassignTags)) { foreach ($this->unassignTags as $tag) { /* @var Tag $tag */ $this->getLog()->debug('Unassigning tag ' . $tag->tag); $tag->unassignCampaign($this->campaignId); $tag->save(); } } if ($this->loaded) { // Manage assignments $this->manageAssignments(); } // Notify anyone interested of the changes $this->notify($options); } /** * Delete Campaign * @throws NotFoundException */ public function delete() { $this->load(); // Unassign all Layouts $this->layouts = []; $this->unlinkLayouts(); // Delete all permissions foreach ($this->permissions as $permission) { /* @var Permission $permission */ $permission->delete(); } // Unassign all Tags foreach ($this->tags as $tag) { /* @var Tag $tag */ $tag->unassignCampaign($this->campaignId); $tag->save(); } // Notify anyone interested of the changes // we do this before we delete from the DB (otherwise notify won't find anything) $this->notify(); // Delete all events foreach ($this->events as $event) { /* @var Schedule $event */ $event->setDisplayFactory($this->displayFactory); $event->delete(); } // Delete the Actual Campaign $this->getStore()->update('DELETE FROM `campaign` WHERE CampaignID = :campaignId', ['campaignId' => $this->campaignId]); } /** * Assign Layout * @param Layout $layout * @throws NotFoundException */ public function assignLayout($layout) { $this->load(); $layout->displayOrder = ($layout->displayOrder == null || $layout->displayOrder == 0) ? count($this->layouts) + 1 : $layout->displayOrder; $found = false; foreach ($this->layouts as $existingLayout) { if ($existingLayout->getId() === $layout->getId() && $existingLayout->displayOrder === $layout->displayOrder) { $found = true; break; } } if (!$found) { $this->getLog()->debug('Layout assignment doesnt exist, adding it. ' . $layout . ', display order ' . $layout->displayOrder); $this->layoutAssignmentsChanged = true; $this->layouts[] = $layout; } } /** * Unassign Layout * @param Layout $layout */ public function unassignLayout($layout) { $this->load(); $countBefore = count($this->layouts); $this->getLog()->debug('Unassigning Layout, count before assign = ' . $countBefore); $found = false; $existingKey = null; foreach ($this->layouts as $key => $existing) { /** @var Layout $existing */ $this->getLog()->debug('Comparing existing [' . $existing->layoutId . ', ' . $existing->displayOrder . '] with unassign [' . $layout->layoutId . ', ' . $layout->displayOrder . '].'); if ($layout->displayOrder == null) { if ($existing->getId() == $layout->getId()) { $found = true; $existingKey = $key; break; } } else { if ($existing->getId() == $layout->getId() && $existing->displayOrder == $layout->displayOrder) { $found = true; $existingKey = $key; break; } } } if ($found) { $this->getLog()->debug('Removing item at key ' . $existingKey); unset($this->layouts[$existingKey]); } $countAfter = count($this->layouts); $this->getLog()->debug('Count after unassign ' . $countAfter); if ($countBefore !== $countAfter) $this->layoutAssignmentsChanged = true; } /** * Is the provided layout already assigned to this campaign * @param Layout $checkLayout * @return bool * @throws XiboException */ public function isLayoutAssigned($checkLayout) { $assigned = false; $this->load(); foreach ($this->layouts as $layout) { if ($layout->layoutId === $checkLayout->layoutId) { $assigned = true; break; } } return $assigned; } private function add() { $this->campaignId = $this->getStore()->insert('INSERT INTO `campaign` (Campaign, IsLayoutSpecific, UserId) VALUES (:campaign, :isLayoutSpecific, :userId)', array( 'campaign' => $this->campaign, 'isLayoutSpecific' => $this->isLayoutSpecific, 'userId' => $this->ownerId )); } private function update() { $this->getStore()->update('UPDATE `campaign` SET campaign = :campaign, userId = :userId WHERE CampaignID = :campaignId', [ 'campaignId' => $this->campaignId, 'campaign' => $this->campaign, 'userId' => $this->ownerId ]); } /** * Manage the assignments */ private function manageAssignments() { if ($this->layoutAssignmentsChanged) { $this->getLog()->debug('Managing Assignments on ' . $this); $this->unlinkLayouts(); $this->linkLayouts(); } else { $this->getLog()->debug('Assignments have not changed on ' . $this); } } /** * Link Layout */ private function linkLayouts() { // Don't do anything if we don't have any layouts if (count($this->layouts) <= 0) return; // Sort the layouts by their display order usort($this->layouts, function($a, $b) { /** @var Layout $a */ /** @var Layout $b */ if ($a->displayOrder === null) return 1; if ($a->displayOrder === $b->displayOrder) return 0; return ($a->displayOrder < $b->displayOrder) ? -1 : 1; }); // Update the layouts, in order to have display order 1 to n $i = 0; $sql = 'INSERT INTO `lkcampaignlayout` (CampaignID, LayoutID, DisplayOrder) VALUES '; $params = []; foreach ($this->layouts as $layout) { $i++; $layout->displayOrder = $i; $sql .= '(:campaignId_' . $i . ', :layoutId_' . $i . ', :displayOrder_' . $i . '),'; $params['campaignId_' . $i] = $this->campaignId; $params['layoutId_' . $i] = $layout->layoutId; $params['displayOrder_' . $i] = $layout->displayOrder; } $sql = rtrim($sql, ','); $this->getStore()->update($sql, $params); } /** * Unlink Layout */ private function unlinkLayouts() { // Delete all the links $this->getStore()->update('DELETE FROM `lkcampaignlayout` WHERE campaignId = :campaignId', ['campaignId' => $this->campaignId]); } /** * Notify displays of this campaign change * @param array $options */ private function notify($options = []) { $options = array_merge([ 'notify' => true, 'collectNow' => true, ], $options); // Do we notify? if ($options['notify']) { $this->getLog()->debug('CampaignId ' . $this->campaignId . ' wants to notify.'); $notify = $this->displayFactory->getDisplayNotifyService(); // Should we collect immediately if ($options['collectNow']) $notify->collectNow(); // Notify $notify->notifyByCampaignId($this->campaignId); } } }