diff options
Diffstat (limited to 'plugins/Annotations/API.php')
-rwxr-xr-x | plugins/Annotations/API.php | 691 |
1 files changed, 338 insertions, 353 deletions
diff --git a/plugins/Annotations/API.php b/plugins/Annotations/API.php index e03f5f5dba..7750c816e3 100755 --- a/plugins/Annotations/API.php +++ b/plugins/Annotations/API.php @@ -12,365 +12,350 @@ /** * @see plugins/Annotations/AnnotationList.php */ -require_once PIWIK_INCLUDE_PATH.'/plugins/Annotations/AnnotationList.php'; +require_once PIWIK_INCLUDE_PATH . '/plugins/Annotations/AnnotationList.php'; /** * API for annotations plugin. Provides methods to create, modify, delete & query * annotations. - * + * * @package Piwik_Annotations */ class Piwik_Annotations_API { - static private $instance = null; - - /** - * Returns this API's singleton instance. - * - * @return Piwik_Annotations_API - */ - static public function getInstance() - { - if (self::$instance == null) - { - self::$instance = new self; - } - return self::$instance; - } - - /** - * Create a new annotation for a site. - * - * @param string $idSite The site ID to add the annotation to. - * @param string $date The date the annotation is attached to. - * @param string $note The text of the annotation. - * @param string $starred Either 0 or 1. Whether the annotation should be starred. - * @return array Returns an array of two elements. The first element (indexed by - * 'annotation') is the new annotation. The second element (indexed - * by 'idNote' is the new note's ID). - */ - public function add( $idSite, $date, $note, $starred = 0 ) - { - $this->checkSingleIdSite($idSite, $extraMessage = "Note: Cannot add one note to multiple sites."); - $this->checkDateIsValid($date); - $this->checkUserCanAddNotesFor($idSite); - - // add, save & return a new annotation - $annotations = new Piwik_Annotations_AnnotationList($idSite); - - $newAnnotation = $annotations->add($idSite, $date, $note, $starred); - $annotations->save($idSite); - - return $newAnnotation; - } - - /** - * Modifies an annotation for a site and returns the modified annotation - * and its ID. - * - * If the current user is not allowed to modify an annotation, an exception - * will be thrown. A user can modify a note if: - * - the user has admin access for the site, OR - * - the user has view access, is not the anonymous user and is the user that - * created the note - * - * @param string $idSite The site ID to add the annotation to. - * @param string $idNote The ID of the note. - * @param string|null $date The date the annotation is attached to. If null, the annotation's - * date is not modified. - * @param string|null $note The text of the annotation. If null, the annotation's text - * is not modified. - * @param string|null $starred Either 0 or 1. Whether the annotation should be starred. - * If null, the annotation is not starred/un-starred. - * @return array Returns an array of two elements. The first element (indexed by - * 'annotation') is the new annotation. The second element (indexed - * by 'idNote' is the new note's ID). - */ - public function save( $idSite, $idNote, $date = null, $note = null, $starred = null ) - { - $this->checkSingleIdSite($idSite, $extraMessage = "Note: Cannot modify more than one note at a time."); - $this->checkDateIsValid($date, $canBeNull = true); - - // get the annotations for the site - $annotations = new Piwik_Annotations_AnnotationList($idSite); - - // check permissions - $this->checkUserCanModifyOrDelete($idSite, $annotations->get($idSite, $idNote)); - - // modify the annotation, and save the whole list - $annotations->update($idSite, $idNote, $date, $note, $starred); - $annotations->save($idSite); - - return $annotations->get($idSite, $idNote); - } - - /** - * Removes an annotation from a site's list of annotations. - * - * If the current user is not allowed to delete the annotation, an exception - * will be thrown. A user can delete a note if: - * - the user has admin access for the site, OR - * - the user has view access, is not the anonymous user and is the user that - * created the note - * - * @param string $idSite The site ID to add the annotation to. - * @param string $idNote The ID of the note to delete. - */ - public function delete( $idSite, $idNote ) - { - $this->checkSingleIdSite($idSite, $extraMessage = "Note: Cannot delete multiple notes."); - - $annotations = new Piwik_Annotations_AnnotationList($idSite); - - // check permissions - $this->checkUserCanModifyOrDelete($idSite, $annotations->get($idSite, $idNote)); - - // remove the note & save the list - $annotations->remove($idSite, $idNote); - $annotations->save($idSite); - } - - /** - * Returns a single note for one site. - * - * @param string $idSite The site ID to add the annotation to. - * @param string $idNote The ID of the note to get. - * @return array The annotation. It will contain the following properties: - * - date: The date the annotation was recorded for. - * - note: The note text. - * - starred: Whether the note is starred or not. - * - user: The user that created the note. - * - canEditOrDelete: Whether the user that called this method can edit or - * delete the annotation returned. - */ - public function get( $idSite, $idNote ) - { - $this->checkSingleIdSite($idSite, $extraMessage = "Note: Specify only one site ID when getting ONE note."); - Piwik::checkUserHasViewAccess($idSite); - - // get single annotation - $annotations = new Piwik_Annotations_AnnotationList($idSite); - return $annotations->get($idSite, $idNote); - } - - /** - * Returns every annotation for a specific site within a specific date range. - * The date range is specified by a date, the period type (day/week/month/year) - * and an optional number of N periods in the past to include. - * - * @param string $idSite The site ID to add the annotation to. Can be one ID or - * a list of site IDs. - * @param string|false $date The date of the period. - * @param string $period The period type. - * @param int|false $lastN Whether to include the last N number of periods in the - * date range or not. - * @return array An array that indexes arrays of annotations by site ID. ie, - * array( - * 5 => array( - * array(...), // annotation #1 - * array(...), // annotation #2 - * ), - * 8 => array(...) - * ) - */ - public function getAll( $idSite, $date = false, $period = 'day', $lastN = false ) - { - Piwik::checkUserHasViewAccess($idSite); - - $annotations = new Piwik_Annotations_AnnotationList($idSite); - - // if date/period are supplied, determine start/end date for search - list($startDate, $endDate) = self::getDateRangeForPeriod($date, $period, $lastN); - - return $annotations->search($startDate, $endDate); - } - - /** - * Returns the count of annotations for a list of periods, including the count of - * starred annotations. - * - * @param string $idSite The site ID to add the annotation to. - * @param string|false $date The date of the period. - * @param string $period The period type. - * @param int|false $lastN Whether to get counts for the last N number of periods or not. - * @return array An array mapping site IDs to arrays holding dates & the count of - * annotations made for those dates. eg, - * array( - * 5 => array( - * array('2012-01-02', array('count' => 4, 'starred' => 2)), - * array('2012-01-03', array('count' => 0, 'starred' => 0)), - * array('2012-01-04', array('count' => 2, 'starred' => 0)), - * ), - * 6 => array( - * array('2012-01-02', array('count' => 1, 'starred' => 0)), - * array('2012-01-03', array('count' => 4, 'starred' => 3)), - * array('2012-01-04', array('count' => 2, 'starred' => 0)), - * ), - * ... - * ) - */ - public function getAnnotationCountForDates( $idSite, $date, $period, $lastN = false, $getAnnotationText = false ) - { - Piwik::checkUserHasViewAccess($idSite); - - // get start & end date for request. lastN is ignored if $period == 'range' - list($startDate, $endDate) = self::getDateRangeForPeriod($date, $period, $lastN); - if ($period == 'range') - { - $period = 'day'; - } - - // create list of dates - $dates = array(); - for (; $startDate->getTimestamp() <= $endDate->getTimestamp(); $startDate = $startDate->addPeriod(1, $period)) - { - $dates[] = $startDate; - } - // we add one for the end of the last period (used in for loop below to bound annotation dates) - $dates[] = $startDate; - - // get annotations for the site - $annotations = new Piwik_Annotations_AnnotationList($idSite); - - // create result w/ 0-counts - $result = array(); - for ($i = 0; $i != count($dates) - 1; ++$i) - { - $date = $dates[$i]; - $nextDate = $dates[$i + 1]; - $strDate = $date->toString(); - - foreach ($annotations->getIdSites() as $idSite) - { - $result[$idSite][$strDate] = $annotations->count($idSite, $date, $nextDate); - - // if only one annotation, return the one annotation's text w/ the counts - if ($getAnnotationText - && $result[$idSite][$strDate]['count'] == 1) - { - $annotationsForSite = $annotations->search( - $date, Piwik_Date::factory($nextDate->getTimestamp() - 1), $idSite); - $annotation = reset($annotationsForSite[$idSite]); - - $result[$idSite][$strDate]['note'] = $annotation['note']; - } - } - } - - // convert associative array into array of pairs (so it can be traversed by index) - $pairResult = array(); - foreach ($result as $idSite => $counts) - { - foreach ($counts as $date => $count) - { - $pairResult[$idSite][] = array($date, $count); - } - } - return $pairResult; - } - - /** - * Throws if the current user is not allowed to modify or delete an annotation. - * - * @param int $idSite The site ID the annotation belongs to. - * @param array $annotation The annotation. - * @throws Exception if the current user is not allowed to modify/delete $annotation. - */ - private function checkUserCanModifyOrDelete( $idSite, $annotation ) - { - if (!$annotation['canEditOrDelete']) - { - throw new Exception(Piwik_Translate('Annotations_YouCannotModifyThisNote')); - } - } - - /** - * Throws if the current user is not allowed to create annotations for a site. - * - * @param int $idSite The site ID. - * @throws Exception if the current user is anonymous or does not have view access - * for site w/ id=$idSite. - */ - private static function checkUserCanAddNotesFor( $idSite ) - { - if (!Piwik_Annotations_AnnotationList::canUserAddNotesFor($idSite)) - { - throw new Exception("The current user is not allowed to add notes for site #$idSite."); - } - } - - /** - * Returns start & end dates for the range described by a period and optional lastN - * argument. - * - * @param string $date|false The start date of the period (or the date range of a range - * period). - * @param string $period The period type ('day', 'week', 'month', 'year' or 'range'). - * @param int|false $lastN Whether to include the last N periods in the range or not. - * Ignored if period == range. - * - * @ignore - */ - public static function getDateRangeForPeriod( $date, $period, $lastN = false ) - { - if ($date === false) - { - return array(false, false); - } - - // if the range is just a normal period (or the period is a range in which case lastN is ignored) - if ($lastN === false - || $period == 'range') - { - if ($period == 'range') - { - $oPeriod = new Piwik_Period_Range('day', $date); - } - else - { - $oPeriod = Piwik_Period::factory($period, Piwik_Date::factory($date)); - } - - $startDate = $oPeriod->getDateStart(); - $endDate = $oPeriod->getDateEnd(); - } - else // if the range includes the last N periods - { - list($date, $lastN) = - Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution::getDateRangeAndLastN($period, $date, $lastN); - list($startDate, $endDate) = explode(',', $date); - - $startDate = Piwik_Date::factory($startDate); - $endDate = Piwik_Date::factory($endDate); - } - return array($startDate, $endDate); - } - - /** - * Utility function, makes sure idSite string has only one site ID and throws if - * otherwise. - */ - private function checkSingleIdSite( $idSite, $extraMessage ) - { - // can only add a note to one site - if (!is_numeric($idSite)) - { - throw new Exception("Invalid idSite: '$idSite'. $extraMessage"); - } - } - - /** - * Utility function, makes sure date string is valid date, and throws if - * otherwise. - */ - private function checkDateIsValid( $date, $canBeNull = false ) - { - if ($date === null - && $canBeNull) - { - return; - } - - Piwik_Date::factory($date); - } + static private $instance = null; + + /** + * Returns this API's singleton instance. + * + * @return Piwik_Annotations_API + */ + static public function getInstance() + { + if (self::$instance == null) { + self::$instance = new self; + } + return self::$instance; + } + + /** + * Create a new annotation for a site. + * + * @param string $idSite The site ID to add the annotation to. + * @param string $date The date the annotation is attached to. + * @param string $note The text of the annotation. + * @param string $starred Either 0 or 1. Whether the annotation should be starred. + * @return array Returns an array of two elements. The first element (indexed by + * 'annotation') is the new annotation. The second element (indexed + * by 'idNote' is the new note's ID). + */ + public function add($idSite, $date, $note, $starred = 0) + { + $this->checkSingleIdSite($idSite, $extraMessage = "Note: Cannot add one note to multiple sites."); + $this->checkDateIsValid($date); + $this->checkUserCanAddNotesFor($idSite); + + // add, save & return a new annotation + $annotations = new Piwik_Annotations_AnnotationList($idSite); + + $newAnnotation = $annotations->add($idSite, $date, $note, $starred); + $annotations->save($idSite); + + return $newAnnotation; + } + + /** + * Modifies an annotation for a site and returns the modified annotation + * and its ID. + * + * If the current user is not allowed to modify an annotation, an exception + * will be thrown. A user can modify a note if: + * - the user has admin access for the site, OR + * - the user has view access, is not the anonymous user and is the user that + * created the note + * + * @param string $idSite The site ID to add the annotation to. + * @param string $idNote The ID of the note. + * @param string|null $date The date the annotation is attached to. If null, the annotation's + * date is not modified. + * @param string|null $note The text of the annotation. If null, the annotation's text + * is not modified. + * @param string|null $starred Either 0 or 1. Whether the annotation should be starred. + * If null, the annotation is not starred/un-starred. + * @return array Returns an array of two elements. The first element (indexed by + * 'annotation') is the new annotation. The second element (indexed + * by 'idNote' is the new note's ID). + */ + public function save($idSite, $idNote, $date = null, $note = null, $starred = null) + { + $this->checkSingleIdSite($idSite, $extraMessage = "Note: Cannot modify more than one note at a time."); + $this->checkDateIsValid($date, $canBeNull = true); + + // get the annotations for the site + $annotations = new Piwik_Annotations_AnnotationList($idSite); + + // check permissions + $this->checkUserCanModifyOrDelete($idSite, $annotations->get($idSite, $idNote)); + + // modify the annotation, and save the whole list + $annotations->update($idSite, $idNote, $date, $note, $starred); + $annotations->save($idSite); + + return $annotations->get($idSite, $idNote); + } + + /** + * Removes an annotation from a site's list of annotations. + * + * If the current user is not allowed to delete the annotation, an exception + * will be thrown. A user can delete a note if: + * - the user has admin access for the site, OR + * - the user has view access, is not the anonymous user and is the user that + * created the note + * + * @param string $idSite The site ID to add the annotation to. + * @param string $idNote The ID of the note to delete. + */ + public function delete($idSite, $idNote) + { + $this->checkSingleIdSite($idSite, $extraMessage = "Note: Cannot delete multiple notes."); + + $annotations = new Piwik_Annotations_AnnotationList($idSite); + + // check permissions + $this->checkUserCanModifyOrDelete($idSite, $annotations->get($idSite, $idNote)); + + // remove the note & save the list + $annotations->remove($idSite, $idNote); + $annotations->save($idSite); + } + + /** + * Returns a single note for one site. + * + * @param string $idSite The site ID to add the annotation to. + * @param string $idNote The ID of the note to get. + * @return array The annotation. It will contain the following properties: + * - date: The date the annotation was recorded for. + * - note: The note text. + * - starred: Whether the note is starred or not. + * - user: The user that created the note. + * - canEditOrDelete: Whether the user that called this method can edit or + * delete the annotation returned. + */ + public function get($idSite, $idNote) + { + $this->checkSingleIdSite($idSite, $extraMessage = "Note: Specify only one site ID when getting ONE note."); + Piwik::checkUserHasViewAccess($idSite); + + // get single annotation + $annotations = new Piwik_Annotations_AnnotationList($idSite); + return $annotations->get($idSite, $idNote); + } + + /** + * Returns every annotation for a specific site within a specific date range. + * The date range is specified by a date, the period type (day/week/month/year) + * and an optional number of N periods in the past to include. + * + * @param string $idSite The site ID to add the annotation to. Can be one ID or + * a list of site IDs. + * @param string|false $date The date of the period. + * @param string $period The period type. + * @param int|false $lastN Whether to include the last N number of periods in the + * date range or not. + * @return array An array that indexes arrays of annotations by site ID. ie, + * array( + * 5 => array( + * array(...), // annotation #1 + * array(...), // annotation #2 + * ), + * 8 => array(...) + * ) + */ + public function getAll($idSite, $date = false, $period = 'day', $lastN = false) + { + Piwik::checkUserHasViewAccess($idSite); + + $annotations = new Piwik_Annotations_AnnotationList($idSite); + + // if date/period are supplied, determine start/end date for search + list($startDate, $endDate) = self::getDateRangeForPeriod($date, $period, $lastN); + + return $annotations->search($startDate, $endDate); + } + + /** + * Returns the count of annotations for a list of periods, including the count of + * starred annotations. + * + * @param string $idSite The site ID to add the annotation to. + * @param string|false $date The date of the period. + * @param string $period The period type. + * @param int|false $lastN Whether to get counts for the last N number of periods or not. + * @return array An array mapping site IDs to arrays holding dates & the count of + * annotations made for those dates. eg, + * array( + * 5 => array( + * array('2012-01-02', array('count' => 4, 'starred' => 2)), + * array('2012-01-03', array('count' => 0, 'starred' => 0)), + * array('2012-01-04', array('count' => 2, 'starred' => 0)), + * ), + * 6 => array( + * array('2012-01-02', array('count' => 1, 'starred' => 0)), + * array('2012-01-03', array('count' => 4, 'starred' => 3)), + * array('2012-01-04', array('count' => 2, 'starred' => 0)), + * ), + * ... + * ) + */ + public function getAnnotationCountForDates($idSite, $date, $period, $lastN = false, $getAnnotationText = false) + { + Piwik::checkUserHasViewAccess($idSite); + + // get start & end date for request. lastN is ignored if $period == 'range' + list($startDate, $endDate) = self::getDateRangeForPeriod($date, $period, $lastN); + if ($period == 'range') { + $period = 'day'; + } + + // create list of dates + $dates = array(); + for (; $startDate->getTimestamp() <= $endDate->getTimestamp(); $startDate = $startDate->addPeriod(1, $period)) { + $dates[] = $startDate; + } + // we add one for the end of the last period (used in for loop below to bound annotation dates) + $dates[] = $startDate; + + // get annotations for the site + $annotations = new Piwik_Annotations_AnnotationList($idSite); + + // create result w/ 0-counts + $result = array(); + for ($i = 0; $i != count($dates) - 1; ++$i) { + $date = $dates[$i]; + $nextDate = $dates[$i + 1]; + $strDate = $date->toString(); + + foreach ($annotations->getIdSites() as $idSite) { + $result[$idSite][$strDate] = $annotations->count($idSite, $date, $nextDate); + + // if only one annotation, return the one annotation's text w/ the counts + if ($getAnnotationText + && $result[$idSite][$strDate]['count'] == 1 + ) { + $annotationsForSite = $annotations->search( + $date, Piwik_Date::factory($nextDate->getTimestamp() - 1), $idSite); + $annotation = reset($annotationsForSite[$idSite]); + + $result[$idSite][$strDate]['note'] = $annotation['note']; + } + } + } + + // convert associative array into array of pairs (so it can be traversed by index) + $pairResult = array(); + foreach ($result as $idSite => $counts) { + foreach ($counts as $date => $count) { + $pairResult[$idSite][] = array($date, $count); + } + } + return $pairResult; + } + + /** + * Throws if the current user is not allowed to modify or delete an annotation. + * + * @param int $idSite The site ID the annotation belongs to. + * @param array $annotation The annotation. + * @throws Exception if the current user is not allowed to modify/delete $annotation. + */ + private function checkUserCanModifyOrDelete($idSite, $annotation) + { + if (!$annotation['canEditOrDelete']) { + throw new Exception(Piwik_Translate('Annotations_YouCannotModifyThisNote')); + } + } + + /** + * Throws if the current user is not allowed to create annotations for a site. + * + * @param int $idSite The site ID. + * @throws Exception if the current user is anonymous or does not have view access + * for site w/ id=$idSite. + */ + private static function checkUserCanAddNotesFor($idSite) + { + if (!Piwik_Annotations_AnnotationList::canUserAddNotesFor($idSite)) { + throw new Exception("The current user is not allowed to add notes for site #$idSite."); + } + } + + /** + * Returns start & end dates for the range described by a period and optional lastN + * argument. + * + * @param string $date|false The start date of the period (or the date range of a range + * period). + * @param string $period The period type ('day', 'week', 'month', 'year' or 'range'). + * @param int|false $lastN Whether to include the last N periods in the range or not. + * Ignored if period == range. + * + * @ignore + */ + public static function getDateRangeForPeriod($date, $period, $lastN = false) + { + if ($date === false) { + return array(false, false); + } + + // if the range is just a normal period (or the period is a range in which case lastN is ignored) + if ($lastN === false + || $period == 'range' + ) { + if ($period == 'range') { + $oPeriod = new Piwik_Period_Range('day', $date); + } else { + $oPeriod = Piwik_Period::factory($period, Piwik_Date::factory($date)); + } + + $startDate = $oPeriod->getDateStart(); + $endDate = $oPeriod->getDateEnd(); + } else // if the range includes the last N periods + { + list($date, $lastN) = + Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution::getDateRangeAndLastN($period, $date, $lastN); + list($startDate, $endDate) = explode(',', $date); + + $startDate = Piwik_Date::factory($startDate); + $endDate = Piwik_Date::factory($endDate); + } + return array($startDate, $endDate); + } + + /** + * Utility function, makes sure idSite string has only one site ID and throws if + * otherwise. + */ + private function checkSingleIdSite($idSite, $extraMessage) + { + // can only add a note to one site + if (!is_numeric($idSite)) { + throw new Exception("Invalid idSite: '$idSite'. $extraMessage"); + } + } + + /** + * Utility function, makes sure date string is valid date, and throws if + * otherwise. + */ + private function checkDateIsValid($date, $canBeNull = false) + { + if ($date === null + && $canBeNull + ) { + return; + } + + Piwik_Date::factory($date); + } } |