[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
05122024
/
htdocs
/
jurnal-kesmas
/
v1
/
plugins
/
reports
/
counter
/
classes
/
COUNTER
/
[
Home
]
File: COUNTER.php
<?php /** * Copyright (c) 2015 University of Pittsburgh * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ namespace COUNTER { /** * COUNTER Reports classes, release 4.1 * Represents the COUNTER XSD schema in class form * * @link http://www.niso.org/schemas/sushi * * @author Clinton Graham, University of Pittsburgh Library System, University of Pittsburgh <ctgraham@pitt.edu> +1-412-383-1057 * @copyright 2015 University of Pittsburgh * @license http://www.gnu.org/licenses/gpl-2.0.html GPL 2.0 or later * * @package COUNTER * * @version 0.3 * * @section DESCRIPTION * * This is a set of classes to represent the Project COUNTER schema ( http://www.projectcounter.org/ ) * It is basically an encapsulation of DOMDocument, with type checking. * Construct any object, then cast it as a string to retrieve the XML, or call asDOMDocument() to retrieve the DOM. * $report = new COUNTER\Report( * 'reportId', * 'reportVersion', * 'reportName', * 'reportTitle', * new COUNTER\Customer( * 'customerId', * new COUNTER\ReportItems( * 'itemPlatform', * 'itemName', * 'Journal', * array( * new COUNTER\Metric( * new COUNTER\DateRange(date_create("first day of previous month"), date_create("last day of previous month")), * 'Requests', * array(new COUNTER\PerformanceCounter('ft_html', 128), new COUNTER\PerformanceCounter('ft_pdf', 129)) * ), * new COUNTER\Metric( * new COUNTER\DateRange(date_create("first day of this month"), date_create("last day of this month")), * 'Requests', * new COUNTER\PerformanceCounter('other', 121) * ) * ) * ) * ), * new COUNTER\Vendor('vendorId') * ); * echo $report; */ /** * COUNTER report builder class * Other classes in this package extend from this core class to have access to several generic functions * * @todo should "tool-like" functions be moved to static calls from an non-inherited Tools class? */ class ReportBuilder { public const COUNTER_NAMESPACE = 'http://www.niso.org/schemas/counter'; /** * Validate that $object is a $className instance. If valid, return the object, otherwise, throw an exception * * @param object $object * @param string $className If no namespace specified, defaults to the COUNTER namespace * * @throws Exception * * @return object */ protected function validateOneOf($object, $className) { if (strpos($className, '\\') === false) { $expectedClassname = 'COUNTER\\' . $className; } elseif (strpos($className, '\\') === 0) { $expectedClassname = substr($className, 1); } else { $expectedClassname = $className; } if (is_null($object)) { throw new \Exception('Invalid object. Expected "' . $expectedClassname . '", got "NULL"'); } if (is_array($object)) { throw new \Exception('Invalid class. Expected "' . $expectedClassname . '", got unparsable array'); } if (is_string($object)) { switch ($className) { case '\DateTime': $date = date_create($object); if ($date) { return $date; } break; default: } throw new \Exception('Invalid class. Expected "' . $expectedClassname . '", got unparsable string'); } if ($expectedClassname == get_class($object) || is_subclass_of($object, $expectedClassname)) { return $object; } throw new \Exception('Invalid class. Expected "' . $expectedClassname . '", got "' . get_class($object) . '"'); } /** * Validate that $objects is an array of $className instances. If valid, return the array, otherwise, throw an exception * * @param object $objects * @param string $className * * @throws Exception * * @return array */ protected function validateOneOrMoreOf($objects, $className) { if (is_array($objects)) { foreach ($objects as $object) { $this->validateOneOf($object, $className); } return $objects; } return [$this->validateOneOf($objects, $className)]; } /** * Validate that $objects is an array of $className instances, or is empty. If valid, return the array or empty, otherwise, throw an exception * * @param object $objects * @param string $className * * @throws Exception * * @return array */ protected function validateZeroOrMoreOf($objects, $className) { if (empty($objects)) { return; } return $this->validateOneOrMoreOf($objects, $className); } /** * Validate that $object is a $className instance, or is empty. If valid, return the object or empty, otherwise, throw an exception * * @param object $object * @param string $className * * @throws Exception * * @return object */ protected function validateZeroOrOneOf($object, $className) { if (empty($object)) { return; } return $this->validateOneOf($object, $className); } /** * Validate that $yr is an integer. If valid, return the year, otherwise, throw an exception * * @param int $int * * @throws Exception * * @return int */ protected function validatePositiveInteger($int) { $intval = intval($int); if (!is_int($intval) || $intval < 0) { throw new \Exception('Invalid positive integer: ' . gettype($int) . ' value ' . $int); } return $intval; } /** * Validate that $string is string. If valid, return the string, otherwise, throw an exception * * @param string $string * * @throws Exception * * @return string */ protected function validateString($string) { if (!is_string($string)) { throw new \Exception('Invalid string: ' . gettype($string)); } return $string; } /** * Validate that $array is an array of strings. If valid, return the array, otherwise, throw an exception * * @param array $array * * @throws Exception * * @return array */ protected function validateStrings($array) { if (is_array($array)) { foreach ($array as $string) { $this->validateString($string); } return $array; } if (is_string($array)) { return [$array]; } if (!empty($array)) { throw new \Exception('Invalid string array: ' . gettype($array)); } } /** * Check an array to see if it has associative (non-numeric) keys * * @param array $array * * @return bool */ protected static function isAssociative($array) { return count(array_filter(array_keys($array), 'is_string')) > 0; } /** * Given an classname and an array, call the $classname::build method and return the built object(s) * The array can be associative (for a single object), or an array of associative arrays (for multiple objects) * * @param string $classname * @param array $array * * @return mixed object or array of objects */ protected function buildMultiple($classname, $array) { if (!is_array($array)) { return []; } if (self::isAssociative($array)) { return $classname::build($array); } $elements = []; foreach ($array as $element) { $elements[] = $classname::build($element); } return $elements; } /** * Return an array of valid Item Data Types * * @return array * * @todo verify addition of "Article" here for proposed release 4.2. */ protected function getItemDataTypes() { return ['Journal', 'Database', 'Platform', 'Book', 'Collection', 'Multimedia', 'Article']; } /** * Return an array of valid Identifier Types * * @return array */ protected function getIdentifierTypes() { return ['Online_ISSN', 'Print_ISSN', 'Online_ISBN', 'Print_ISBN', 'DOI', 'Proprietary']; } /** * Return an array of valid Contributor Identifier Types * * @return array */ protected function getContributorIdentifierTypes() { return ['ORCID', 'ISNI', 'Proprietary']; } /** * Return an array of valid Date Types * * @return array * * @todo these values are preliminary; need an update from COUNTER */ protected function getDateTypes() { return ['PubDate', 'FirstAccessedOnline', 'Proprietary']; } /** * Return an array of valid Date Types * * @return array * * @todo these values are preliminary; need an update from COUNTER */ protected function getAttributeTypes() { return ['ArticleVersion', 'ArticleType', 'QualificationName', 'QualificationLevel']; } /** * Return an array of valid Metric Types * * @return array */ protected function getMetricTypes() { return ['abstract', 'audio', 'data_set', 'ft_epub', 'ft_html', 'ft_html_mobile', 'ft_pdf', 'ft_pdf_mobile', 'ft_ps', 'ft_ps_mobile', 'ft_total', 'image', 'multimedia', 'no_license', 'other', 'podcast', 'record_view', 'reference', 'result_click', 'search_fed', 'search_reg', 'sectioned_html', 'toc', 'turnaway', 'video']; } /** * Return an array of valid Categories * * @return array */ protected function getCategories() { return ['Requests', 'Searches', 'Access_denied']; } /** * Output this object as XML * Inherited by all children of this object; all children must implement asDOMDocument(). * * @return string */ public function __toString() { $doc = $this->asDOMDocument(); $doc->formatOutput = true; return $doc->saveXML(); } /** * Do NOT Output this object as a DOMDocument * This method must be implemented in the subclass * * @throws Exception */ public function asDOMDocument() { throw new \Exception(get_class($this) . ' does not implement asDOMDocument()'); } /** * Do NOT build this object * This method must be implemented in the subclass * Subclasses should call this method if unable to build the object in order to report an error. * * @throws Exception */ public static function build($array) { throw new \Exception('Failed to build ' . static::class . ' from data ' . var_export($array, true)); } } /** * COUNTER reports base class * */ class Reports extends ReportBuilder { /** * @var array one or more COUNTER\Report objects */ private $report = []; /** * Construct the object * * @param array $reports COUNTER\Report array * * @throws Exception */ public function __construct($reports) { $this->report = $this->validateOneOrMoreOf($reports, 'Report'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Report'])) { // Nicely structured associative array $reports = parent::buildMultiple('COUNTER\Report', $array['Report']); return new self($reports); } if (!parent::isAssociative($array)) { // Just an array of reports $reports = parent::buildMultiple('COUNTER\Report', $array); return new self($reports); } } parent::build($array); } /** * Add a report * * @param object $report CounterReport * * @throws Exception */ public function addReport($report) { $this->report[] = $this->validateOneOf($report, 'Report'); } /** * Get an array of reports * * @return array COUNTER\Report array */ public function getReports() { return $this->report; } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElementNS(self::COUNTER_NAMESPACE, 'Reports')); $xmlns = $doc->createAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation'); $xmlns->value = self::COUNTER_NAMESPACE . ' http://www.niso.org/schemas/sushi/counter4_1.xsd'; $root->appendChild($xmlns); foreach ($this->report as $rep) { $root->appendChild($doc->importNode($rep->asDOMDocument()->documentElement, true)); } return $doc; } } /** * COUNTER report instance class */ class Report extends ReportBuilder { /** * @var string Report attribute "Created" */ private $created; /** * @var string Report attribute "ID" */ private $id; /** * @var string Report attribute "Version" */ private $version; /** * @var string Report attribute "Name" */ private $name; /** * @var string Report attribute "Title" */ private $title; /** * @var COUNTER\Vendor */ private $vendor; /** * @var array one or more COUNTER\Customer objects */ private $customer; /** * Construct the object * * @param string $id * @param string $version * @param string $name * @param string $title * @param string $customers COUNTER\Customer * @param object $vendor COUNTER\Vendor array * @param string $created optional * * @throws Exception */ public function __construct($id, $version, $name, $title, $customers, $vendor, $created = '') { foreach (['id', 'version', 'name', 'title', 'created'] as $arg) { $this->$arg = $this->validateString($$arg); } if (!$created) { $this->created = date("Y-m-d\Th:i:sP"); } $this->vendor = $this->validateOneOf($vendor, 'Vendor'); $this->customer = $this->validateOneOrMoreOf($customers, 'Customer'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['ID']) && isset($array['Version']) && isset($array['Name']) && isset($array['Title']) && isset($array['Customer']) && isset($array['Vendor'])) { // Nicely structured associative array $customers = parent::buildMultiple('COUNTER\Customer', $array['Customer']); return new self( $array['ID'], $array['Version'], $array['Name'], $array['Title'], $customers, Vendor::build($array['Vendor']), $array['Created'] ?? '' ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Report')); foreach (['Created', 'ID', 'Version', 'Name', 'Title'] as $arg) { $lcarg = strtolower($arg); $attrAttr = $doc->createAttribute($arg); $attrAttr->appendChild($doc->createTextNode($this->$lcarg)); $root->appendChild($attrAttr); } $root->appendChild($doc->importNode($this->vendor->asDOMDocument()->documentElement, true)); foreach ($this->customer as $customer) { $root->appendChild($doc->importNode($customer->asDOMDocument()->documentElement, true)); } return $doc; } } /** * COUNTER vendor class */ class Vendor extends ReportBuilder { /** * @var string Vendor element "Name" */ private $name; /** * @var string Vendor element "ID" */ private $id; /** * @var array zero or more COUNTER\Contact elements */ private $contact = []; /** * @var string Vendor element "WebSiteUrl" */ private $webSiteUrl; /** * @var string Vendor element "LogoUrl" */ private $logoUrl; /** * Construct the object * * @param string $id * @param string $name optional * @param array $contacts optional COUNTER\Contact array * @param string $webSiteUrl optional * @param string $logoUrl optional * * @throws Exception */ public function __construct($id, $name = '', $contacts = [], $webSiteUrl = '', $logoUrl = '') { foreach (['id', 'name', 'webSiteUrl', 'logoUrl'] as $arg) { $this->$arg = $this->validateString($$arg); } $this->contact = $this->validateZeroOrMoreOf($contacts, 'Contact'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['ID'])) { // Nicely structured associative array $contacts = parent::buildMultiple('COUNTER\Contact', $array['Contact'] ?? []); return new self( $array['ID'], $array['Name'] ?? '', $contacts, $array['WebSiteUrl'] ?? '', $array['LogoUrl'] ?? '' ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Vendor')); if ($this->name) { $root->appendChild($doc->createElement('Name'))->appendChild($doc->createTextNode($this->name)); } $root->appendChild($doc->createElement('ID'))->appendChild($doc->createTextNode($this->id)); if ($this->contact) { foreach ($this->contact as $contact) { $root->appendChild($doc->importNode($contact->asDOMDocument()->documentElement, true)); } } if ($this->webSiteUrl) { $root->appendChild($doc->createElement('WebSiteUrl'))->appendChild($doc->createTextNode($this->webSiteUrl)); } if ($this->logoUrl) { $root->appendChild($doc->createElement('LogoUrl'))->appendChild($doc->createTextNode($this->logoUrl)); } return $doc; } } /** * COUNTER contact class */ class Contact extends ReportBuilder { /** * @var string Contact element "Contact" */ private $contact; /** * @var string Contact element "Email" */ private $email; /** * Construct the object * * @param string $contact optional * @param string $email optional * * @throws Exception */ public function __construct($contact = '', $email = '') { foreach (['contact', 'email'] as $arg) { $this->$arg = $this->validateString($$arg); } } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['E-mail'])) { $array['Email'] = $array['E-mail']; unset($array['E-mail']); } if (isset($array['Contact']) || isset($array['Email'])) { return new self($array['Contact'] ? $array['Contact'] : '', $array['Email'] ? $array['Email'] : ''); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (name/email => name/email) foreach ($array as $k => $v) { if (filter_var($k, FILTER_VALIDATE_EMAIL)) { // email => name return new self($v, $k); } // name => email return new self($k, $v); } } elseif (count(array_keys($array)) == 1 && !parent::isAssociative($array)) { // Loosely array with a name or email if (filter_var($k, FILTER_VALIDATE_EMAIL)) { // email return new self('', $array[0]); } // name return new self($array[0]); } } elseif (is_string($array)) { // Just a name or email if (filter_var($array, FILTER_VALIDATE_EMAIL)) { // email return new self('', $array); } // name return new self($array); } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Contact')); if ($this->contact) { $root->appendChild($doc->createElement('Contact'))->appendChild($doc->createTextNode($this->contact)); } if ($this->email) { $root->appendChild($doc->createElement('E-mail'))->appendChild($doc->createTextNode($this->email)); } return $doc; } } /** * COUNTER customer class */ class Customer extends ReportBuilder { /** * @var string Customer element "Name" */ private $name; /** * @var string Customer element "ID" */ private $id; /** * @var array zero or more COUNTER\Contact elements */ private $contact; /** * @var string Customer element "WebSiteUrl" */ private $webSiteUrl; /** * @var string Customer element "LogoUrl" */ private $logoUrl; /** * @var string Customer element "Consortium" */ private $consortium; /** * @var array zero or more COUNTER\Identifier elements */ private $institutionalIdentifier; /** * @var array one or more COUNTER\ReportItem elements */ private $reportItems; /** * Construct the object * * @param string $id * @param array $reportItems COUNTER\ReportItems array * @param string $name optional * @param array $contacts optional COUNTER\Contacts array * @param string $webSiteUrl optional * @param string $logoUrl optional * @param object $consortium optional COUNTER\Consortium * @param array $institutionalIdentifier optional COUNTER\Identifier array * * @throws Exception */ public function __construct($id, $reportItems, $name = '', $contacts = [], $webSiteUrl = '', $logoUrl = '', $consortium = null, $institutionalIdentifier = []) { foreach (['id', 'name', 'webSiteUrl', 'logoUrl'] as $arg) { $this->$arg = $this->validateString($$arg); } $this->reportItems = $this->validateOneOrMoreOf($reportItems, 'ReportItems'); $this->contact = $this->validateZeroOrMoreOf($contacts, 'Contact'); $this->consortium = $this->validateZeroOrOneOf($consortium, 'Consortium'); $this->institutionalIdentifier = $this->validateZeroOrMoreOf($institutionalIdentifier, 'Identifier'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['ID']) && isset($array['ReportItems'])) { // Nicely structured associative array $items = parent::buildMultiple('COUNTER\ReportItems', $array['ReportItems']); $ids = parent::buildMultiple('COUNTER\Identifier', $array['InstitutionalIdentifier'] ?? []); $contacts = parent::buildMultiple('COUNTER\Contact', $array['Contact'] ?? []); return new self( $array['ID'], $items, $array['Name'] ?? '', $contacts, $array['WebSiteUrl'] ?? '', $array['LogoUrl'] ?? '', isset($array['Consortium']) ? Consortium::build($array['Consortium']) : null, $ids ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Customer')); if ($this->name) { $root->appendChild($doc->createElement('Name'))->appendChild($doc->createTextNode($this->name)); } $root->appendChild($doc->createElement('ID'))->appendChild($doc->createTextNode($this->id)); if ($this->contact) { foreach ($this->contact as $contact) { $root->appendChild($doc->importNode($contact->asDOMDocument()->documentElement, true)); } } if ($this->webSiteUrl) { $root->appendChild($doc->createElement('WebSiteUrl'))->appendChild($doc->createTextNode($this->webSiteUrl)); } if ($this->logoUrl) { $root->appendChild($doc->createElement('LogoUrl'))->appendChild($doc->createTextNode($this->logoUrl)); } if ($this->consortium) { $root->appendChild($doc->importNode($this->consortium->asDOMDocument()->documentElement, true)); } if ($this->institutionalIdentifier) { foreach ($this->institutionalIdentifier as $id) { $root->appendChild($doc->importNode($id->asDOMDocument()->documentElement, true)); } } foreach ($this->reportItems as $rep) { $root->appendChild($doc->importNode($rep->asDOMDocument()->documentElement, true)); } return $doc; } } /** * COUNTER consortium class */ class Consortium extends ReportBuilder { /** * @var string Consortium element "Code" */ private $code; /** * @var string Consortium element "WellKnownName" */ private $wellKnownName; /** * Construct the object * * @param string $wellKnownName * @param string $code optional */ public function __construct($wellKnownName, $code = '') { foreach (['wellKnownName', 'code'] as $arg) { $this->$arg = $this->validateString($$arg); } } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['WellKnownName'])) { // Nicely structured associative array return new self($array['WellKnownName'], $array['Code'] ? $array['Code'] : ''); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (name => code) foreach ($array as $k => $v) { return new self($k, $v); } } elseif (count(array_keys($array)) == 1 && !parent::isAssociative($array)) { // Loosely array with a name return new self($array[0]); } } elseif (is_string($array)) { // Just a name return new self($array); } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Consortium')); if ($this->code) { $root->appendChild($doc->createElement('Code'))->appendChild($doc->createTextNode($this->code)); } $root->appendChild($doc->createElement('WellKnownName'))->appendChild($doc->createTextNode($this->wellKnownName)); return $doc; } } /** * COUNTER report item class */ class ReportItems extends ReportBuilder { /** * @var COUNTER\ParentItem ReportItem element "ParentItem" */ private $parentItem; /** * @var array zero or more COUNTER\Identifier elements */ private $itemIdentifier; /** * @var array zero or more COUNTER\ItemContributor elements */ private $itemContributor; /** * @var array zero or more COUNTER\ItemDate elements */ private $itemDate; /** * @var array zero or more COUNTER\ItemAttribute elements */ private $itemAttribute; /** * @var string ReportItem element "ItemPlatform" */ private $itemPlatform; /** * @var string ReportItem element "ItemPublisher" */ private $itemPublisher; /** * @var string ReportItem element "ItemName" */ private $itemName; /** * @var COUNTER\ItemDataType ReportItem element "ItemData" */ private $itemDataType; /** * @var array one or more COUNTER\Metric elements */ private $itemPerformance; /** * Construct the object * * @param string $itemPlatform * @param string $itemName * @param string $itemDataType * @param array $itemPerformance COUNTER\Metric array * @param object $parentItem optional COUNTER\ParentItem * @param array $itemIdentifiers optional COUNTER\Identifier array * @param array $itemContributors optional COUNTER\Contributor array * @param array $itemDates optional COUNTER\Date array * @param array $itemAttributes optional COUNTER\ItemAttribute array * @param string $itemPublisher optional * * @throws Exception */ public function __construct($itemPlatform, $itemName, $itemDataType, $itemPerformance, $parentItem = null, $itemIdentifiers = [], $itemContributors = [], $itemDates = [], $itemAttributes = [], $itemPublisher = '') { foreach (['itemPlatform', 'itemPublisher', 'itemName', 'itemDataType'] as $arg) { $this->$arg = $this->validateString($$arg); } if (!in_array($itemDataType, $this->getItemDataTypes())) { throw new \Exception('Invalid item data type: ' . $itemDataType); } $this->itemPerformance = $this->validateOneOrMoreOf($itemPerformance, 'Metric'); $this->parentItem = $this->validateZeroOrOneOf($parentItem, 'ParentItem'); $this->itemIdentifier = $this->validateZeroOrMoreOf($itemIdentifiers, 'Identifier'); $this->itemContributor = $this->validateZeroOrMoreOf($itemContributors, 'ItemContributor'); $this->itemDate = $this->validateZeroOrMoreOf($itemDates, 'ItemDate'); $this->itemAttribute = $this->validateZeroOrMoreOf($itemAttributes, 'ItemAttribute'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['ItemPlatform']) && isset($array['ItemName']) && isset($array['ItemDataType']) && isset($array['ItemPerformance'])) { // Nicely structured associative array $performance = parent::buildMultiple('COUNTER\Metric', $array['ItemPerformance']); $ids = parent::buildMultiple('COUNTER\Identifier', $array['ItemIdentifier'] ?? []); $contributors = parent::buildMultiple('COUNTER\ItemContributor', $array['ItemContributor'] ?? []); $dates = parent::buildMultiple('COUNTER\ItemDate', $array['ItemDate'] ?? []); $attributes = parent::buildMultiple('COUNTER\ItemAttribute', $array['ItemAttribute'] ?? []); return new self( $array['ItemPlatform'], $array['ItemName'], $array['ItemDataType'], $performance, isset($array['ParentItem']) ? ParentItem::build($array['ParentItem']) : null, $ids, $contributors, $dates, $attributes, $array['ItemPublisher'] ?? '' ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ReportItems')); if ($this->parentItem) { $root->appendChild($doc->importNode($this->parentItem->asDOMDocument()->documentElement, true)); } if ($this->itemIdentifier) { foreach ($this->itemIdentifier as $id) { $root->appendChild($doc->importNode($id->asDOMDocument()->documentElement, true)); } } if ($this->itemContributor) { foreach ($this->itemContributor as $contrib) { $root->appendChild($doc->importNode($contrib->asDOMDocument()->documentElement, true)); } } if ($this->itemDate) { foreach ($this->itemDate as $date) { $root->appendChild($doc->importNode($date->asDOMDocument()->documentElement, true)); } } if ($this->itemAttribute) { foreach ($this->itemAttribute as $attrib) { $root->appendChild($doc->importNode($attrib->asDOMDocument()->documentElement, true)); } } $root->appendChild($doc->createElement('ItemPlatform'))->appendChild($doc->createTextNode($this->itemPlatform)); if ($this->itemPublisher) { $root->appendChild($doc->createElement('ItemPublisher'))->appendChild($doc->createTextNode($this->itemPublisher)); } $root->appendChild($doc->createElement('ItemName'))->appendChild($doc->createTextNode($this->itemName)); $root->appendChild($doc->createElement('ItemDataType'))->appendChild($doc->createTextNode($this->itemDataType)); foreach ($this->itemPerformance as $perf) { $root->appendChild($doc->importNode($perf->asDOMDocument()->documentElement, true)); } return $doc; } } /** * COUNTER parent item class */ class ParentItem extends ReportBuilder { /** * @var array zero or more COUNTER\Identifier elements */ private $itemIdentifier; /** * @var array zero or more COUNTER\ItemContributor elements */ private $itemContributor; /** * @var array zero or more COUNTER\ItemDate elements */ private $itemDate; /** * @var array zero or more COUNTER\ItemAttribute elements */ private $itemAttribute; /** * @var string ParentItem element "ItemPublisher" */ private $itemPublisher; /** * @var string ParentItem element "ItemName" */ private $itemName; /** * @var COUNTER\DataType ParentItem element "ItemDataType" */ private $itemDataType; /** * Construct the object * * @param string $itemName * @param string $itemDataType * @param array $itemIdentifiers optional COUNTER\Identifier array * @param array $itemContributors optional COUNTER\ItemContributor array * @param array $itemDates optional COUNTER\ItemDate array * @param array $itemAttributes optional COUNTER\ItemAttribute array * @param string $itemPublisher optional * * @throws Exception */ public function __construct($itemName, $itemDataType, $itemIdentifiers = [], $itemContributors = [], $itemDates = [], $itemAttributes = [], $itemPublisher = '') { foreach (['itemName', 'itemDataType', 'itemPublisher'] as $arg) { $this->$arg = $this->validateString($$arg); } if (!in_array($itemDataType, $this->getItemDataTypes())) { throw new \Exception('Invalid type: ' . $type); } $this->itemIdentifier = $this->validateZeroOrMoreOf($itemIdentifiers, 'Identifier'); $this->itemContributor = $this->validateZeroOrMoreOf($itemContributors, 'ItemContributor'); $this->itemDate = $this->validateZeroOrMoreOf($itemDates, 'ItemDate'); $this->itemAttribute = $this->validateZeroOrMoreOf($itemAttributes, 'ItemAttribute'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['ItemName']) && isset($array['ItemDataType'])) { // Nicely structured associative array $ids = parent::buildMultiple('COUNTER\Identifier', $array['ItemIdentifier'] ?? []); $contributors = parent::buildMultiple('COUNTER\ItemContributor', $array['ItemContributor'] ?? []); $dates = parent::buildMultiple('COUNTER\ItemDate', $array['ItemDate'] ?? []); $attributes = parent::buildMultiple('COUNTER\ItemAttribute', $array['ItemAttribute'] ?? []); return new self( $array['ItemName'], $array['ItemDataType'], $ids, $contributors, $dates, $attributes, $array['ItemPublisher'] ?? '' ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ParentItem')); if ($this->itemIdentifier) { foreach ($this->itemIdentifier as $id) { $root->appendChild($doc->importNode($id->asDOMDocument()->documentElement, true)); } } if ($this->itemContributor) { foreach ($this->itemContributor as $contrib) { $root->appendChild($doc->importNode($contrib->asDOMDocument()->documentElement, true)); } } if ($this->itemDate) { foreach ($this->itemDate as $date) { $root->appendChild($doc->importNode($date->asDOMDocument()->documentElement, true)); } } if ($this->itemAttribute) { foreach ($this->itemAttribute as $attrib) { $root->appendChild($doc->importNode($attrib->asDOMDocument()->documentElement, true)); } } if ($this->itemPublisher) { $root->appendChild($doc->createElement('ItemPublisher'))->appendChild($doc->createTextNode($this->itemPublisher)); } $root->appendChild($doc->createElement('ItemName'))->appendChild($doc->createTextNode($this->itemName)); $root->appendChild($doc->createElement('ItemDataType'))->appendChild($doc->createTextNode($this->itemDataType)); return $doc; } } /** * COUNTER item contributor class */ class ItemContributor extends ReportBuilder { /** * @var array zero or more COUNTER\ItemContributorID elements */ private $itemContributorId; /** * @var string ItemContributor element "Name" */ private $itemContributorName; /** * @var string ItemContributor element "Affiliation" */ private $itemContributorAffiliation; /** * @var string ItemContributor element "Role" */ private $itemContributorRole; /** * Construct the object * * @param array $itemContributorIds optional COUNTER\ContributorId array * @param string $itemContributorName optional * @param array $itemContributorAffiliations optional string array * @param array $itemContributorRoles optional string array * * @throws Exception */ public function __construct($itemContributorIds = [], $itemContributorName = '', $itemContributorAffiliations = [], $itemContributorRoles = []) { $this->itemContributorId = $this->validateZeroOrMoreOf($itemContributorIds, 'ItemContributorId'); $this->itemContributorName = $this->validateString($itemContributorName); $this->itemContributorAffiliation = $this->validateStrings($itemContributorAffiliations); $this->itemContributorRole = $this->validateStrings($itemContributorRoles); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['ItemContributorID']) || isset($array['ItemContributorName']) || isset($array['ItemContributorAffiliation']) || isset($array['ItemContributorRole'])) { // Nicely structured associative array $ids = parent::buildMultiple('COUNTER\ItemContributorId', $array['ItemContributorID'] ?? []); return new self( $ids, $array['ItemContributorName'] ?? '', $array['ItemContributorAffiliation'] ?? '', $array['ItemContributorRole'] ?? '' ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ItemContributor')); if ($this->itemContributorId) { foreach ($this->itemContributorId as $id) { $root->appendChild($doc->importNode($id->asDOMDocument()->documentElement, true)); } } if ($this->itemContributorName) { $root->appendChild($doc->createElement('ItemContributorName'))->appendChild($doc->createTextNode($this->itemContributorName)); } if ($this->itemContributorAffiliation) { foreach ($this->itemContributorAffiliation as $affiliation) { $root->appendChild($doc->createElement('ItemContributorAffiliation', $affiliation)); } } if ($this->itemContributorRole) { foreach ($this->itemContributorRole as $role) { $root->appendChild($doc->createElement('ItemContributorRole', $role)); } } return $doc; } } /** * COUNTER contributor id class */ class ItemContributorId extends ReportBuilder { /** * @var string ItemContributorID element "Type" */ private $type; /** * @var string ItemContributorID element "Value" */ private $value; /** * Construct the object * * @param string $type * @param string $value * * @throws Exception */ public function __construct($type, $value) { foreach (['type', 'value'] as $arg) { $this->$arg = $this->validateString($$arg); } if (!in_array($type, $this->getContributorIdentifierTypes())) { throw new \Exception('Invalid type: ' . $type); } } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Type']) && isset($array['Value'])) { // Nicely structured associative array return new self($array['Type'], $array['Value']); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (type => value) foreach ($array as $k => $v) { return new self($k, $v); } } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ItemContributorID')); $root->appendChild($doc->createElement('Type'))->appendChild($doc->createTextNode($this->type)); $root->appendChild($doc->createElement('Value'))->appendChild($doc->createTextNode($this->value)); return $doc; } } /** * COUNTER item identifier class */ class Identifier extends ReportBuilder { /** * @var string Identifier element "Type" */ private $type; /** * @var string Identifier element "Type" */ private $value; /** * Construct the object * * @param string $type * @param string $value * * @throws Exception */ public function __construct($type, $value) { foreach (['type', 'value'] as $arg) { $this->$arg = $this->validateString($$arg); } if (!in_array($type, $this->getIdentifierTypes())) { throw new \Exception('Invalid type: ' . $type); } } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Type']) && isset($array['Value'])) { // Nicely structured associative array return new self($array['Type'], $array['Value']); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (type => value) foreach ($array as $k => $v) { return new self($k, $v); } } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ItemIdentifier')); $root->appendChild($doc->createElement('Type'))->appendChild($doc->createTextNode($this->type)); $root->appendChild($doc->createElement('Value'))->appendChild($doc->createTextNode($this->value)); return $doc; } } /** * COUNTER item date class */ class ItemDate extends ReportBuilder { /** * @var string ItemDate element "Type" */ private $type; /** * @var string ItemDate element "Value" */ private $value; /** * Construct the object * * @param string $type * @param string $value * * @throws Exception */ public function __construct($type, $value) { $this->type = $this->validateString($type); if (!in_array($type, $this->getDateTypes())) { throw new \Exception('Invalid type: ' . $type); } $this->value = $this->validateOneOf($value, '\DateTime'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Type']) && isset($array['Value'])) { // Nicely structured associative array return new self($array['Type'], $array['Value']); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (type => value) foreach ($array as $k => $v) { return new self($k, $v); } } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ItemDate')); $root->appendChild($doc->createElement('Type'))->appendChild($doc->createTextNode($this->type)); $root->appendChild($doc->createElement('Value'))->appendChild($doc->createTextNode(date_format($this->value, 'Y-m-d'))); return $doc; } } /** * COUNTER item attribute class */ class ItemAttribute extends ReportBuilder { /** * @var string ItemAttribute element "Type" */ private $type; /** * @var string ItemAttribute element "Value" */ private $value; /** * Construct the object * * @param string $type * @param string $value * * @throws Exception */ public function __construct($type, $value) { foreach (['type', 'value'] as $arg) { $this->$arg = $this->validateString($$arg); } if (!in_array($type, $this->getAttributeTypes())) { throw new \Exception('Invalid type: ' . $type); } } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Type']) && isset($array['Value'])) { // Nicely structured associative array return new self($array['Type'], $array['Value']); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (type => value) foreach ($array as $k => $v) { return new self($k, $v); } } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ItemAttribute')); $root->appendChild($doc->createElement('Type'))->appendChild($doc->createTextNode($this->type)); $root->appendChild($doc->createElement('Value'))->appendChild($doc->createTextNode($this->value)); return $doc; } } /** * COUNTER performance counter class */ class Metric extends ReportBuilder { /** * @var int Metric element "PubYr" */ private $pubYr; /** * @var int Metric element "PubYrFrom" */ private $pubYrFrom; /** * @var int Metric element "PubYrTo" */ private $pubYrTo; /** * @var COUNTER\DateRange Metric element "Period" */ private $period; /** * @var COUNTER\Category Metric element "Category" */ private $category; /** * @var array one or more COUNTER\PerformanceCounter elements */ private $instance; /** * Construct the object * * @param array $period COUNTER\DateRange array * @param array $category COUNTER\Category array * @param array $instances COUNTER\PerformanceCounter array * @param int $pubYrFrom optional * @param int $pubYrTo optional * @param int $pubYr optional * @param null|mixed $pubYrFrom * @param null|mixed $pubYrTo * @param null|mixed $pubYr * * @throws Exception */ public function __construct($period, $category, $instances, $pubYrFrom = null, $pubYrTo = null, $pubYr = null) { $this->period = $this->validateOneOf($period, 'DateRange'); $this->category = $this->validateString($category); if (!in_array($category, $this->getCategories())) { throw new \Exception('Invalid category: ' . $category); } $this->instance = $this->validateOneOrMoreOf($instances, 'PerformanceCounter'); if ($pubYrFrom) { $this->pubYrFrom = $this->validatePositiveInteger($pubYrFrom); } if ($pubYrTo) { $this->pubYrTo = $this->validatePositiveInteger($pubYrTo); } if ($pubYr) { $this->pubYr = $this->validatePositiveInteger($pubYr); } } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Period']) && isset($array['Instance']) && isset($array['Category'])) { // Nicely structured associative array $instances = parent::buildMultiple('COUNTER\PerformanceCounter', $array['Instance']); return new self( DateRange::build($array['Period']), $array['Category'], $instances, $array['PubYrFrom'] ?? null, $array['PubYrTo'] ?? null, $array['PubYr'] ?? null ); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('ItemPerformance')); if ($this->period) { $root->appendChild($doc->importNode($this->period->asDOMDocument()->documentElement, true)); } if ($this->category) { $root->appendChild($doc->createElement('Category'))->appendChild($doc->createTextNode($this->category)); } foreach ($this->instance as $instance) { $root->appendChild($doc->importNode($instance->asDOMDocument()->documentElement, true)); } foreach (['pubYr', 'pubYrFrom', 'pubYrTo'] as $pubYrKey) { if ($this->$pubYrKey) { $root->appendChild($doc->createElement(ucfirst($pubYrKey)))->appendChild($doc->createTextNode($this->$pubYrKey)); $attr = $doc->createAttribute(ucfirst($pubYrKey)); $attr->value = $this->$pubYrKey; $root->appendChild($attr); } } return $doc; } } /** * COUNTER date range class */ class DateRange extends ReportBuilder { /** * @var \DateTime DateRange element "Begin" */ private $begin; /** * @var \DateTime DateRange element "End" */ private $end; /** * Construct the object * * @param DateTime $begin * @param DateTime $end * * @throws Exception */ public function __construct($begin, $end) { $this->begin = $this->validateOneOf($begin, '\DateTime'); $this->end = $this->validateOneOf($end, '\DateTime'); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['Begin']) && isset($array['End'])) { // Nicely structured associative array return new self($array['Begin'], $array['End']); } if (count(array_keys($array)) == 2 && !parent::isAssociative($array)) { // Unstructured array of two elements, assume begin and end dates return new self($array[0], $array[1]); } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Period')); $root->appendChild($doc->createElement('Begin'))->appendChild($doc->createTextNode(date_format($this->begin, 'Y-m-d'))); $root->appendChild($doc->createElement('End'))->appendChild($doc->createTextNode(date_format($this->end, 'Y-m-d'))); return $doc; } } /** * COUNTER performance counter class */ class PerformanceCounter extends ReportBuilder { /** * @var COUNTER\MetricType PerformanceCounter element "MetricType" */ private $metricType; /** * @var int PerformanceCounter element "Count" */ private $count; /** * Construct the object * * @param string $metricType * @param int $count * * @throws Exception */ public function __construct($metricType, $count) { $this->metricType = $this->validateString($metricType); if (!in_array($metricType, $this->getMetricTypes())) { throw new \Exception('Invalid metric type: ' . $metricType); } $this->count = $this->validatePositiveInteger($count); } /** * Construct the object from an array * * @param array $array Hash of key-values * * @throws Exception * * @return \self */ public static function build($array) { if (is_array($array)) { if (isset($array['MetricType']) && isset($array['Count'])) { // Nicely structured associative array return new self($array['MetricType'], $array['Count']); } if (count(array_keys($array)) == 1 && parent::isAssociative($array)) { // Loosely structured associative array (type => count) foreach ($array as $k => $v) { return new self($k, $v); } } } parent::build($array); } /** * Output this object as a DOMDocument * * @return DOMDocument */ public function asDOMDocument() { $doc = new \DOMDocument(); $root = $doc->appendChild($doc->createElement('Instance')); $root->appendChild($doc->createElement('MetricType'))->appendChild($doc->createTextNode($this->metricType)); $root->appendChild($doc->createElement('Count'))->appendChild($doc->createTextNode($this->count)); return $doc; } } }