1939 lines
66 KiB
PHP
1939 lines
66 KiB
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;
|
|
}
|
|
}
|
|
|
|
}
|