Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

Commit de15f71e authored by Olivier Lequeux's avatar Olivier Lequeux
Browse files

2nd commit

parent 4793a24c
<?php
namespace Lavoisier;
/**
* Created by JetBrains PhpStorm.
* User: Olivier LEQUEUX
* Date: 28/10/13
*/
use \Lavoisier\IEntries;
class Entries extends \ArrayObject implements IEntries
{
public function init()
{
}
public function pop()
{
$iterator = $this->getIterator();
$iterator->rewind();
$item = null;
if ($iterator->valid()) {
$item = $iterator->current();
}
return $item;
}
/**
* deprecated, uses for tests
* @return array
*/
public
function getArrayCopy()
{
$result = parent::getArrayCopy();
foreach ($result as $key => $item) {
if (is_object($item)) {
$result[$key] = $result[$key]->getArrayCopy();
}
}
return $result;
}
public
function asXmlEntries()
{
return self::convertToEntries($this);
}
static protected function convertToEntries($data)
{
$xml = '<e:entries xmlns:e="http://software.in2p3.fr/lavoisier/entries.xsd">';
foreach ($data as $key => $entry) {
if (is_array($entry)) {
$xml .= self::convertToEntries($entry);
} else {
$xml .= '<e:entry key ="' . $key . '">' . $entry . '</e:entry>';
}
}
return $xml . '</e:entries>';
}
public function setValue($name, $value)
{
$this[$name] = $value;
}
public function getValue($name)
{
return $this[$name];
}
}
\ No newline at end of file
<?php
namespace Lavoisier\Exceptions;
use \Lavoisier\Query;
class HTTPStatusException extends \Exception
{
private $userMessage = null;
function __construct(Query $q, $HTTPCode, $content)
{
$this->userMessage = Query::$HTTP_STATUS_MAP[$HTTPCode] . " => " . trim($content);
if ($HTTPCode == '404') {
$this->userMessage .= " with the following query : " . $q->getUrl();
if ($q->getMethod() === 'POST') {
$pFields = $q->getPostFields();
$pFieldsAsString = '';
foreach ($pFields as $key => $value) {
$pFieldsAsString .= " &$key=$value";
}
$this->userMessage .= " and the POSTed fields : " .$pFieldsAsString;
}
}
parent::__construct($this->userMessage, 0);
}
}
\ No newline at end of file
<?php
namespace Lavoisier\Exceptions;
use \Lavoisier\Query;
class cURLException extends \Exception
{
private $userMessage = null;
function __construct(Query $q, $curlError)
{
$this->userMessage = "[ERROR] " . $curlError;
parent::__construct($this->userMessage, 0);
}
}
\ No newline at end of file
<?php
namespace Lavoisier\Hydrators;
use \Lavoisier\IHydrator;
/**
* @author Olivier LEQUEUX
* hydrate parsing lavoisier XML format after a CSV file conversion
*/
class CSVasXMLHydrator implements IHydrator
{
function hydrate($str)
{
$rows = simplexml_load_string($str);
$result = new \ArrayObject();
foreach ($rows as $row) {
foreach ($row as $row) {
$tmp_col = new \ArrayObject();
foreach ($row as $column) {
$col_attr = $column->attributes();
$tmp_col[strval($col_attr['label'])] = strval($column);
}
$result->append($tmp_col);
}
}
return $result;
}
}
\ No newline at end of file
<?php
namespace Lavoisier\Hydrators;
use \Lavoisier\IHydrator;
class DefaultHydrator implements IHydrator{
public function hydrate($str) {
return $str;
}
}
\ No newline at end of file
<?php
namespace Lavoisier\Hydrators;
use \Lavoisier\IHydrator;
use \Lavoisier\IEntries;
use \Lavoisier\Entries;
class EntriesHydrator implements IHydrator
{
private $value_as_key;
private $rootBinding;
private $keyBinding;
private $defaultBinding;
public function __construct()
{
$this->value_as_key = false;
$this->rootBinding = '\Lavoisier\Entries';
$this->keyBinding = array();
$this->defaultBinding = '\Lavoisier\Entries';
}
public function setValueAsKey($value_as_key)
{
$this->value_as_key = $value_as_key;
}
public function setRootBinding($class) {
$this->rootBinding = $class;
}
public function setDefaultBinding($class) {
$this->defaultBinding = $class;
}
public function setKeyBinding(array $keyClassMap) {
$this->keyBinding = $keyClassMap;
}
public function hydrate($str)
{
$sxObject = new \SimpleXMLIterator($str, 0, false, 'e', true);
if ($sxObject === false) {
throw new \Exception('Unable to parse XML');
}
$res = $this->sxiToArray(
$sxObject,
new $this->rootBinding);
return $res;
}
protected function createEntriesInstance($key)
{
if(is_string($key) && isset($this->keyBinding[$key])) {
$class = $this->keyBinding[$key];
return new $class;
}
else {
return new $this->defaultBinding;
}
}
public function sxiToArray($sxi, IEntries $a)
{
for ($sxi->rewind(); $sxi->valid(); $sxi->next()) {
$key = $this->getAttributeKey($sxi, $a);
if ($sxi->hasChildren()) {
$obj = $this->sxiToArray($sxi->current(), $this->createEntriesInstance($key));
$obj->init();
if ($key === null) {
$a[] = $obj;
} else {
$a[$key] = $obj;
}
} else {
$str = strval($sxi->current());
if ($this->value_as_key == true) {
$key = $str;
}
if ($key === null) {
$a[] = $str;
} else {
$a[$key] = $str;
}
}
}
$a->init();
return $a;
}
private function getAttributeKey(\SimpleXMLElement $sxi, $a)
{
$attr = $sxi->current()->attributes();
$prefixed_attr = $sxi->current()->attributes('e', true);
$key = $sxi->key();
if (isset($attr['key'])) {
$key = strval($attr['key']);
} else {
if (isset($prefixed_attr['key'])) {
$key = strval($prefixed_attr['key']);
} else {
if (!array_key_exists($sxi->key(), $a)) {
$key = null;
}
}
}
return $key;
}
}
\ No newline at end of file
<?php
namespace Lavoisier\Hydrators;
use \Lavoisier\IHydrator;
class SimpleXMLHydrator implements IHydrator
{
public function hydrate($str)
{
$sxObject = simplexml_load_string($str, '\SimpleXMLElement');
if ($sxObject === false) {
throw new \Exception('Unable to parse XML');
}
return $sxObject;
}
}
\ No newline at end of file
<?php
/*
* @todo check if this class is use full when http code return will be properly managed in Lavoisier/Query
* @todo ?accept=txt should be sufficient
*/
namespace Lavoisier\Hydrators;
use \Lavoisier\IHydrator;
class StringHydrator implements IHydrator{
public function hydrate($str) {
$sxObject = new \SimpleXMLElement($str, 0, false, 'e', true);
if ($sxObject === false) {
throw new \Exception('Unable to parse XML');
}
return (strval($sxObject->entry));
}
}
\ No newline at end of file
<?php
namespace Lavoisier;
/**
* @author Olivier LEQUEUX
*/
interface IEntries {
function init();
}
<?php
namespace Lavoisier;
/**
* @author Olivier LEQUEUX
*/
interface IHydrator {
function hydrate($str);
}
<?php
namespace Lavoisier;
/**
* Created by JetBrains PhpStorm.
* User: Olivier LEQUEUX
* Date: 22/10/13
*/
use \Lavoisier\IHydrator;
use \Lavoisier\Hydrators\DefaultHydrator;
use \Lavoisier\Exceptions\HTTPStatusException;
use \Lavoisier\Exceptions\cURLException;
class Query
{
static private $queryTemplates;
private $is_secure;
private $schema;
private $hostname;
private $port;
private $operation;
private $view;
private $path;
private $accept;
private $hydrator;
private $method; //can be set to 'GET' or 'POST'
private $post_fields;
private $connection_timeout_ms;
private $timeout_ms;
public static $HTTP_STATUS_MAP = array(
'401' => '[HTTP 401] Lavoisier authentication problem',
'403' => '[HTTP 403] Lavoisier authorization problem',
'404' => '[HTTP 404] Lavoisier execution failed'
);
public function __construct($hostname, $view = '', $operation = 'lavoisier', $accept='xml')
{
$this->setIsSecure(false);
$this->hostname = $hostname;
$this->port = '8080';
$this->operation = $operation;
$this->view = $view;
$this->path = '';
$this->accept = $accept;
$this->query_field = false;
$this->method = 'GET';
self::$queryTemplates = array(
'lavoisier' => "%s%s:%s/%s/%s%s%saccept=%s",
'lavoisier_base' => "%s%s:%s/%s/%s%s",
'notify' => "%s%s:%s/%s/%s",
'resources' => "%s%s:%s/%s/%s"
);
$this->hydrator = new DefaultHydrator();
$this->timeout_ms = 500;
$this->connect_timeout_ms = 500;
$this->post_fields = array();
}
public function setIsSecure($is_secure)
{
$this->is_secure = $is_secure;
if ($this->is_secure === true) {
$this->schema = 'https://';
} else {
$this->schema = 'http://';
}
}
public function setPort($port)
{
$this->port = $port;
}
public function setOperation($operation)
{
$this->operation = $operation;
}
public function setView($view)
{
$this->view = $view;
}
public function setPath($str)
{
$this->path = $str;
}
public function getPath()
{
return $this->path;
}
public function setMethod($method)
{
if (($method === 'GET') or ($method === 'POST')) {
$this->method = $method;
} else {
throw new \Exception ("Please use 'GET' or 'POST' method, the '$method' method is unknown");
}
}
public function getMethod()
{
return $this->method;
}
public function setHydrator(IHydrator $hydrator)
{
$this->hydrator = $hydrator;
}
public function setConnectionTimeoutMS($connect_timeout_ms)
{
$this->connect_timeout_ms = $connect_timeout_ms;
}
public function setTimeoutMS($connect_timeout_ms)
{
$this->timeout_ms = $connect_timeout_ms;
}
public function setPostFields(array $post_fields)
{
$this->post_fields = $post_fields;
}
public function getPostFields()
{
return $this->post_fields;
}
static public function getQueryTemplate($operation = null)
{
if ($operation === null) {
return self::$queryTemplates;
}
if (!isset(self::$queryTemplates[$operation])) {
throw new \Exception("$operation 'operation' is not recognized by Lavoisier service");
} else {
return self::$queryTemplates[$operation];
}
}
public function curl()
{
// init curl session
$ch = curl_init(($this->getUrl(true)));
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); // no cache, force new connection
// timeout values
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout_ms);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connection_timeout_ms);
// header
curl_setopt($ch, CURLOPT_HEADER, false); // no header in string returned
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // get result from request as string (otherwise through browser)
if ($this->method === 'POST') {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, self::urlify($this->post_fields));
}
$content = curl_exec($ch);
$response = curl_getinfo($ch);
$response['last_curl_error'] = curl_error($ch);
$response['content'] = $content;
curl_close($ch); // close cURL session
return $response;
}
static private function sprintfPredicate($key, $value, $entriesMode = null)
{
if ($entriesMode !== null) {
return sprintf("%s='%s'", $key, $value);
} else {
if (is_array($value)) {
$string = '';
$counter = 0;
foreach ($value as $subValue) {
if ($counter != 0) {
$string .= ' or ';
}
$string .= sprintf("(@key='%s' and text()='%s')", $key, $subValue);
$counter++;
}
return $string;
} else {
return sprintf("(@key='%s' and text()='%s')", $key, $value);
}
}
}
static private function genericBuildPredicate(array $values, $uniqueKey = null, $operator = 'or')
{
$predicate = 'true()';
$compute = true;
foreach ($values as $key => $value) {
if(!empty($value)) {
if ($uniqueKey !== null) $key = $uniqueKey;
if (is_array($value)) $compute = (count($value) > 0 ? true : false);
if (($predicate === 'true()') && ($compute)) {
$predicate = self::sprintfPredicate($key, $value, $uniqueKey);
} else {
if ($compute) {
$predicate = sprintf(" %s %s %s",
$predicate, $operator, self::sprintfPredicate($key, $value, $uniqueKey));
}
}
}
}
$predicate = trim($predicate);
return $predicate;
}
static public function buildPredicate($test, array $values, $operator = 'or')
{
return self::genericBuildPredicate($values, $test, $operator);
}
static public function buildEntriesPredicate(array $whereClauses, $operator = 'or')
{
return self::genericBuildPredicate($whereClauses, null, $operator);
}
/**
* convert map to &key=value url style
* @static
* @param array $fields, tuple of key/values to convert
*/
static public function urlify(array $fields)
{
$fields_string = array();
foreach ($fields as $key => $value) {
if(!empty($value)) {
$fields_string[] = sprintf('%s=%s', $key, $value);
}
}
return implode('&', $fields_string);
}