/plugins/SegmentEditor/API.php
PHP | 334 lines | 318 code | 3 blank | 13 comment | 0 complexity | d2a88f58ac350ab92559f7277b9848e1 MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
- <?php
- /**
- * Piwik - free/libre analytics platform
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
- *
- */
- namespace Piwik\Plugins\SegmentEditor;
- use Exception;
- use Piwik\Common;
- use Piwik\Date;
- use Piwik\Db;
- use Piwik\Piwik;
- use Piwik\Config;
- use Piwik\Plugins\UsersManager\UsersManager;
- use Piwik\Segment;
- /**
- * The SegmentEditor API lets you add, update, delete custom Segments, and list saved segments.a
- *
- * @method static \Piwik\Plugins\SegmentEditor\API getInstance()
- */
- class API extends \Piwik\Plugin\API
- {
- protected function checkSegmentValue($definition, $idSite)
- {
- // unsanitize so we don't record the HTML entitied segment
- $definition = Common::unsanitizeInputValue($definition);
- $definition = str_replace("#", '%23', $definition); // hash delimiter
- $definition = str_replace("'", '%27', $definition); // not encoded in JS
- $definition = str_replace("&", '%26', $definition);
- try {
- $segment = new Segment($definition, $idSite);
- $segment->getHash();
- } catch (Exception $e) {
- throw new Exception("The specified segment is invalid: " . $e->getMessage());
- }
- return $definition;
- }
- protected function checkSegmentName($name)
- {
- if (empty($name)) {
- throw new Exception("Invalid name for this custom segment.");
- }
- }
- protected function checkEnabledAllUsers($enabledAllUsers)
- {
- $enabledAllUsers = (int)$enabledAllUsers;
- if ($enabledAllUsers
- && !Piwik::hasUserSuperUserAccess()
- ) {
- throw new Exception("enabledAllUsers=1 requires Super User access");
- }
- return $enabledAllUsers;
- }
- protected function checkIdSite($idSite)
- {
- if (empty($idSite)) {
- if (!Piwik::hasUserSuperUserAccess()) {
- throw new Exception($this->getMessageCannotEditSegmentCreatedBySuperUser());
- }
- } else {
- if (!is_numeric($idSite)) {
- throw new Exception("idSite should be a numeric value");
- }
- Piwik::checkUserHasViewAccess($idSite);
- }
- $idSite = (int)$idSite;
- return $idSite;
- }
- protected function checkAutoArchive($autoArchive, $idSite)
- {
- $autoArchive = (int)$autoArchive;
- if ($autoArchive) {
- $exception = new Exception("To prevent abuse, autoArchive=1 requires Super User or ControllerAdmin access.");
- if (empty($idSite)) {
- if (!Piwik::hasUserSuperUserAccess()) {
- throw $exception;
- }
- } else {
- if (!Piwik::isUserHasAdminAccess($idSite)) {
- throw $exception;
- }
- }
- }
- return $autoArchive;
- }
- protected function getSegmentOrFail($idSegment)
- {
- $segment = $this->get($idSegment);
- if (empty($segment)) {
- throw new Exception("Requested segment not found");
- }
- return $segment;
- }
- protected function checkUserIsNotAnonymous()
- {
- if (Piwik::isUserIsAnonymous()) {
- throw new Exception("To create, edit or delete Custom Segments, please sign in first.");
- }
- }
- protected function checkUserCanAddNewSegment($idSite)
- {
- if(!$this->isUserCanAddNewSegment($idSite)) {
- throw new Exception(Piwik::translate('SegmentEditor_YouDontHaveAccessToCreateSegments'));
- }
- }
- public function isUserCanAddNewSegment($idSite)
- {
- if(Piwik::isUserIsAnonymous()) {
- return false;
- }
- $requiredAccess = Config::getInstance()->General['adding_segment_requires_access'];
- $authorized =
- ($requiredAccess == 'view' && Piwik::isUserHasViewAccess($idSite)) ||
- ($requiredAccess == 'admin' && Piwik::isUserHasAdminAccess($idSite)) ||
- ($requiredAccess == 'superuser' && Piwik::hasUserSuperUserAccess())
- ;
- return $authorized;
- }
- protected function checkUserCanEditOrDeleteSegment($segment)
- {
- if(Piwik::hasUserSuperUserAccess()) {
- return;
- }
- $this->checkUserIsNotAnonymous();
- if($segment['login'] != Piwik::getCurrentUserLogin()) {
- throw new Exception($this->getMessageCannotEditSegmentCreatedBySuperUser());
- }
- }
- /**
- * Deletes a stored segment.
- *
- * @param $idSegment
- * @return bool
- */
- public function delete($idSegment)
- {
- $segment = $this->getSegmentOrFail($idSegment);
- $this->checkUserCanEditOrDeleteSegment($segment);
- /**
- * Triggered before a segment is deleted or made invisible.
- *
- * This event can be used by plugins to throw an exception
- * or do something else.
- *
- * @param int $idSegment The ID of the segment being deleted.
- */
- Piwik::postEvent('SegmentEditor.deactivate', array($idSegment));
- $db = Db::get();
- $db->delete(Common::prefixTable('segment'), 'idsegment = ' . $idSegment);
- return true;
- }
- /**
- * Modifies an existing stored segment.
- *
- * @param int $idSegment The ID of the stored segment to modify.
- * @param string $name The new name of the segment.
- * @param string $definition The new definition of the segment.
- * @param bool $idSite If supplied, associates the stored segment with as single site.
- * @param bool $autoArchive Whether to automatically archive data with the segment or not.
- * @param bool $enabledAllUsers Whether the stored segment is viewable by all users or just the one that created it.
- *
- * @return bool
- */
- public function update($idSegment, $name, $definition, $idSite = false, $autoArchive = false, $enabledAllUsers = false)
- {
- $segment = $this->getSegmentOrFail($idSegment);
- $this->checkUserCanEditOrDeleteSegment($segment);
- $idSite = $this->checkIdSite($idSite);
- $this->checkSegmentName($name);
- $definition = $this->checkSegmentValue($definition, $idSite);
- $enabledAllUsers = $this->checkEnabledAllUsers($enabledAllUsers);
- $autoArchive = $this->checkAutoArchive($autoArchive, $idSite);
- $bind = array(
- 'name' => $name,
- 'definition' => $definition,
- 'enable_all_users' => $enabledAllUsers,
- 'enable_only_idsite' => $idSite,
- 'auto_archive' => $autoArchive,
- 'ts_last_edit' => Date::now()->getDatetime(),
- );
- /**
- * Triggered before a segment is modified.
- *
- * This event can be used by plugins to throw an exception
- * or do something else.
- *
- * @param int $idSegment The ID of the segment which visibility is reduced.
- */
- Piwik::postEvent('SegmentEditor.update', array($idSegment, $bind));
- $db = Db::get();
- $db->update(Common::prefixTable("segment"),
- $bind,
- "idsegment = $idSegment"
- );
- return true;
- }
- /**
- * Adds a new stored segment.
- *
- * @param string $name The new name of the segment.
- * @param string $definition The new definition of the segment.
- * @param bool $idSite If supplied, associates the stored segment with as single site.
- * @param bool $autoArchive Whether to automatically archive data with the segment or not.
- * @param bool $enabledAllUsers Whether the stored segment is viewable by all users or just the one that created it.
- *
- * @return int The newly created segment Id
- */
- public function add($name, $definition, $idSite = false, $autoArchive = false, $enabledAllUsers = false)
- {
- $this->checkUserCanAddNewSegment($idSite);
- $idSite = $this->checkIdSite($idSite);
- $this->checkSegmentName($name);
- $definition = $this->checkSegmentValue($definition, $idSite);
- $enabledAllUsers = $this->checkEnabledAllUsers($enabledAllUsers);
- $autoArchive = $this->checkAutoArchive($autoArchive, $idSite);
- $db = Db::get();
- $bind = array(
- 'name' => $name,
- 'definition' => $definition,
- 'login' => Piwik::getCurrentUserLogin(),
- 'enable_all_users' => $enabledAllUsers,
- 'enable_only_idsite' => $idSite,
- 'auto_archive' => $autoArchive,
- 'ts_created' => Date::now()->getDatetime(),
- 'deleted' => 0,
- );
- $db->insert(Common::prefixTable("segment"), $bind);
- return $db->lastInsertId();
- }
- /**
- * Returns a stored segment by ID
- *
- * @param $idSegment
- * @throws Exception
- * @return bool
- */
- public function get($idSegment)
- {
- Piwik::checkUserHasSomeViewAccess();
- if (!is_numeric($idSegment)) {
- throw new Exception("idSegment should be numeric.");
- }
- $segment = Db::get()->fetchRow("SELECT * " .
- " FROM " . Common::prefixTable("segment") .
- " WHERE idsegment = ?", $idSegment);
- if (empty($segment)) {
- return false;
- }
- try {
- if (!$segment['enable_all_users']) {
- Piwik::checkUserHasSuperUserAccessOrIsTheUser($segment['login']);
- }
- } catch (Exception $e) {
- throw new Exception($this->getMessageCannotEditSegmentCreatedBySuperUser());
- }
- if ($segment['deleted']) {
- throw new Exception("This segment is marked as deleted. ");
- }
- return $segment;
- }
- /**
- * Returns all stored segments.
- *
- * @param bool|int $idSite Whether to return stored segments for a specific idSite, or all of them. If supplied, must be a valid site ID.
- * @return array
- */
- public function getAll($idSite = false)
- {
- if (!empty($idSite)) {
- Piwik::checkUserHasViewAccess($idSite);
- } else {
- Piwik::checkUserHasSomeViewAccess();
- }
- $userLogin = Piwik::getCurrentUserLogin();
- $model = new Model();
- if (empty($idSite)) {
- $segments = $model->getAllSegments($userLogin);
- } else {
- $segments = $model->getAllSegmentsForSite($idSite, $userLogin);
- }
- return $segments;
- }
- /**
- * @return string
- */
- private function getMessageCannotEditSegmentCreatedBySuperUser()
- {
- $message = "You can only edit and delete custom segments that you have created yourself. This segment was created and 'shared with you' by the Super User. " .
- "To modify this segment, you can first create a new one by clicking on 'Add new segment'. Then you can customize the segment's definition.";
- return $message;
- }
- }