Newer
Older
<?php
namespace SGalinski\TypoScriptReferenceFrontend\Service;
use SGalinski\TypoScriptReferenceFrontend\Domain\Model\Attribute;
use SGalinski\TypoScriptReferenceFrontend\Domain\Model\Property;
use SGalinski\TypoScriptReferenceFrontend\Domain\Model\Type;
use SGalinski\TypoScriptReferenceFrontend\Utilities\Conversion;
use TYPO3\Flow\Annotations as Flow;
/**
* The Class TsrefRestService contains methods for communication with TypoScript REST API.
*
* @package SGalinski\TypoScriptReferenceFrontend\Service
* @Flow\Scope("singleton")
*/
class TsrefRestService {
/**
* Default typo3 version of typoScript types and properties.
* Filtering by this version (very high number) will fetch properties and types of current version.
const TYPO3_DEFAULT_VERSION = '99999';
/**
* A label to be used in URL instead of TYPO3_DEFAULT_VERSION.
* In REST requests, TYPO3_DEFAULT_VERSION is sent instead of this label.
*/
const TYPO3_CURRENT_VERSION_LABEL = 'current';
* @var string
* @Flow\Inject(setting="backendWriteAccessToken")
*/
protected $backendWriteAccessToken;
/**
* URL of REST API resource.
*
* @var string
* @Flow\Inject(setting="resourceUrl")
/**
* TypoScriptGroup string to int mapping.
*
* @var array
*/
protected $typoScriptGroupMapping = [
'typoscript' => Attribute::NORMAL_GROUP,
'user-tsconfig' => Attribute::USER_GROUP,
'page-tsconfig' => Attribute::PAGE_GROUP
];
/**
* Makes curl handle, sets some general options and returns the handle.
* It also checks if cURL is installed.
*
* @param string $suffix
protected function initialiseCurl($suffix) {
// is cURL installed yet?
if (!function_exists('curl_init')) {
throw new \RuntimeException('Sorry cURL is not installed. Install cURL.');
}
$curlHandle = curl_init();
curl_setopt($curlHandle, CURLOPT_URL, $this->resourceUrl . '/api' . $suffix);
// Should cURL return or print out the data? (true = return, false = print)
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, TRUE);
// Timeout in seconds
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 30);
* Fetches types from web resource: RESOURCE_URL.
*
* @param boolean|null $isType - filters by isType
* @param bool $namesOnly - get urlNames and names only of types.
* @param string $typo3Version - filters by typo3Version
* @param string $typoScriptGroup - filters by typo3Group
* @return mixed
*/
public function getAttributesJson(
$isType = NULL, $namesOnly = TRUE, $typo3Version = self::TYPO3_DEFAULT_VERSION,
$resourceName = 'properties';
$headerProperties = [
'namesonly: ' . ($namesOnly ? '1' : '0'),
'version: ' . $typo3Version,
];
if ($isType !== NULL) {
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/' . $resourceName);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $headerProperties);
// Download the given URL, and return output
$output = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
// Close the cURL resource, and free system resources
curl_close($curlHandle);
return $output;
}
* Returns a property\type by its ID from RESOURCE_URL.
* @param string $resourceName ('properties' or 'types')
* @param int $attributeId
public function getAttributeByIdJson($resourceName, $attributeId, $typoScriptGroup) {
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/' . $resourceName . '/' . $attributeId);
// Download the given URL, and return output
$output = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
// Close the cURL resource, and free system resources
curl_close($curlHandle);
return $output;
}
damjan
committed
/**
* Returns a type by its name from RESOURCE_URL.
*
* @param string $typeUrlName
damjan
committed
* @return mixed JSON
*/
public function getTypeByUrlNameJson($typeUrlName, $typoScriptGroup) {
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/types/' . $typeUrlName . '/byurlname');
damjan
committed
// Download the given URL, and return output
$output = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
damjan
committed
// Close the cURL resource, and free system resources
curl_close($curlHandle);
damjan
committed
return $output;
}
/**
* Gets type by name.
*
* @param string $typeUrlName
damjan
committed
* @return \stdClass
*/
public function getTypeByUrlName($typeUrlName, $typoScriptGroup) {
$typeJson = $this->getTypeByUrlNameJson($typeUrlName, $typoScriptGroup);
damjan
committed
$typePhp = json_decode($typeJson);
return $typePhp;
}
* Returns properties of a type by its ID from RESOURCE_URL/propertiesID/byparenttype.
* @param string $typo3Version
* @return mixed
*/
public function getPropertiesByParentTypeIdJson(
$typeId, $typo3Version = self::TYPO3_DEFAULT_VERSION, $typoScriptGroup
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/properties/' . $typeId . '/byparenttype');
$headerProperties = [
'version: ' . $typo3Version,
];
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $headerProperties);
// Download the given URL, and return output
$output = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
// Close the cURL resource, and free system resources
curl_close($curlHandle);
return $output;
}
/**
public function getTypeById($typeId, $typoScriptGroup) {
$typeJson = $this->getAttributeByIdJson('types', $typeId, $typoScriptGroup);
$typePhp = json_decode($typeJson);
return $typePhp;
* @return \stdClass
*/
public function getPropertyById($propertyId, $typoScriptGroup) {
$propertyJson = $this->getAttributeByIdJson('properties', $propertyId, $typoScriptGroup);
$propertyPhp = json_decode($propertyJson);
return $propertyPhp;
}
/**
* Gets all properties by parent type id, $typo3Version and $typoScriptGroup from RESOURCE_URL
*
* @param int $parentTypeId
* @param string $typo3Version
* @return mixed
*/
public function getPropertiesByParentTypeId(
$parentTypeId, $typo3Version = self::TYPO3_DEFAULT_VERSION, $typoScriptGroup
$propertiesJson = $this->getPropertiesByParentTypeIdJson($parentTypeId, $typo3Version, $typoScriptGroup);
$propertiesPhp = json_decode($propertiesJson);
return $propertiesPhp;
}
* Gets all types by $typo3Version and $typoScriptGroup from RESOURCE_URL
* @param bool $namesOnly
public function getTypes(
$namesOnly = TRUE, $typo3Version = self::TYPO3_DEFAULT_VERSION, $typoScriptGroup
$typesJson = $this->getAttributesJson(TRUE, $namesOnly, $typo3Version, $typoScriptGroup);
$typesPhp = json_decode($typesJson);
return $typesPhp;
}
* Adds new type to REST API resource by use of POST method.
* @return mixed
public function addNewType(Type $type, $typoScriptGroup) {
$typeJson = json_encode($type->toArray());
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/types');
curl_setopt($curlHandle, CURLOPT_POST, 1);
$outputJson = $this->submit($curlHandle, $typeJson);
return $outputJson;
}
/**
* Adds new property to REST API resource by use of POST method.
*
* @param Property $property
public function addNewProperty(Property $property, $typoScriptGroup) {
$propertyJson = json_encode($property->toArray());
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/properties');
curl_setopt($curlHandle, CURLOPT_POST, 1);
$outputJson = $this->submit($curlHandle, $propertyJson);
}
/**
* Sends edited type to REST API resource by use of PUT method.
* @return mixed
*/
public function editType(Type $type, $typoScriptGroup) {
if ($type->getId() === NULL) {
throw new \RuntimeException(
'Edited type: ' . ($type->getName() ? $type->getName() : '...') . ' doesnt have ID.'
);
}
$typeJson = json_encode($type->toArray(TRUE));
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/types/' . $type->getId());
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'PUT');
$outputJson = $this->submit($curlHandle, $typeJson);
return $outputJson;
}
/**
* Sends edited property to REST API resource by use of PUT method.
*
* @param Property $property
public function editProperty(Property $property, $typoScriptGroup) {
if ($property->getId() === NULL) {
throw new \RuntimeException(
'Edited property: ' . ($property->getName() ? $property->getName() : '...') . ' doesnt have ID.'
);
}
$dataJson = json_encode($property->toArray(TRUE));
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/properties/' . $property->getId());
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'PUT');
$outputJson = $this->submit($curlHandle, $dataJson);
return $outputJson;
* Changes only those fields specified in the array $data. Type to change is specified with $id.
*
* @param int $id
* @param array $data
public function patchType($id, array $data, $typoScriptGroup) {
if ($id === NULL) {
throw new \RuntimeException(
'$id must not be NULL.'
);
}
$dataJson = json_encode($data);
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/types/' . $id);
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'PATCH');
$outputJson = $this->submit($curlHandle, $dataJson);
return $outputJson;
}
/**
* Changes only those fields specified in the array $data. Property to change is specified with $id.
*
* @param int $id
* @param array $data
public function patchProperty($id, array $data, $typoScriptGroup) {
if ($id === NULL) {
throw new \RuntimeException(
'$id must not be NULL.'
);
}
$dataJson = json_encode($data);
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/properties/' . $id);
curl_setopt($curlHandle, CURLOPT_CUSTOMREQUEST, 'PATCH');
$outputJson = $this->submit($curlHandle, $dataJson);
return $outputJson;
}
/**
* Downloads typo script reference xml from web resource.
*
* @param string $typo3Version
public function getTsrefXml($typo3Version = self::TYPO3_DEFAULT_VERSION, $typoScriptGroup) {
$curlHandle = $this->initialiseCurl('/' . $typoScriptGroup . '/tsref');
$headerProperties = [
'version: ' . $typo3Version,
];
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, $headerProperties);
curl_setopt($curlHandle, CURLOPT_FAILONERROR, 1);
curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION, 1);
// Download the given URL, and return output
$output = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
// Close the cURL resource, and free system resources
/**
* Gets all categories from web resource and returns them as array.
*
* @return mixed
*/
public function getCategoriesJson() {
$curlHandle = $this->initialiseCurl('/categories');
// Download the given URL, and return output
$output = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
// Close the cURL resource, and free system resources
curl_close($curlHandle);
return $output;
}
/**
* Gets all categories from web resource and returns them as stdClass.
*
* @return mixed
*/
public function getCategories() {
$categoriesJson = $this->getCategoriesJson();
$categoriesPhp = json_decode($categoriesJson);
return $categoriesPhp;
}
/**
* Returns associative array of all typo3 groups.
*
* @return array
*/
public function getAllTypo3Groups() {
return [
Attribute::NORMAL_GROUP => 'Normal TypoScript',
Attribute::PAGE_GROUP => 'Page TypoScript',
Attribute::USER_GROUP => 'User TypoScript',
/**
* Returns associative array of available typo3 versions.
*
* @return array
*/
public function getTypo3Versions() {
return [
TsrefRestService::TYPO3_CURRENT_VERSION_LABEL => 'Current',
/**
* Gets en array of types for given TYPO3 version. The types are fetched with name and id only.
*
* @param string $typo3Version
* @return array
*/
public function getTypesWithNull($typo3Version, $typoScriptGroup) {
$typesAssociative = Conversion::typesToAssociativeIdArray(
$this->getTypes(TRUE, $typo3Version, $typoScriptGroup)
);
$typesAssociative = [-1 => 'No type (NULL)'] + $typesAssociative;
return $typesAssociative;
}
/**
* Checks if there was en error in response and trows exception.
*
* @param $statusCode
* @param $outputJson
*/
protected function checkForErrors($statusCode, $outputJson) {
if (gettype($statusCode) === 'integer' && $statusCode >= 400) {
$outputObject = json_decode($outputJson);
$message = isset($outputObject->message) ? $outputObject->message : NULL;
throw new \RuntimeException($message, $statusCode);
}
}
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
/**
* Submits by CURL json data and validates response.
*
* @param $curlHandle
* @param $dataJson
* @return mixed
*/
protected function submit($curlHandle, $dataJson) {
curl_setopt(
$curlHandle, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'accesstoken: ' . $this->backendWriteAccessToken
]
);
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $dataJson);
// Download the given URL, and return output
$outputJson = curl_exec($curlHandle);
$statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
// Close the cURL resource, and free system resources
curl_close($curlHandle);
$this->checkForErrors($statusCode, $outputJson);
return $outputJson;
}
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
/**
* Returns ID (integer representation) of given tpoScript group.
*
* @param string $typoScriptGroupName
* @return int
*/
public function getTypoScriptGroupId($typoScriptGroupName) {
if (!array_key_exists($typoScriptGroupName, $this->typoScriptGroupMapping)) {
throw new \RuntimeException('TypoScript group \'' . $typoScriptGroupName . '\' doesn\'t exist.');
}
return $this->typoScriptGroupMapping[$typoScriptGroupName];
}
/**
* Returns typoScript group name for given ID.
*
* @param int $typoScriptGroupId
* @return string
*/
public function getTypoScriptGroupName($typoScriptGroupId) {
if (!in_array($typoScriptGroupId, $this->typoScriptGroupMapping)) {
throw new \RuntimeException('Invalid tpoScript group ID: \'' . $typoScriptGroupId . '\'.');
}
$typoScriptGroupInverseMapping = array_flip($this->typoScriptGroupMapping);
return $typoScriptGroupInverseMapping[$typoScriptGroupId];
}