<?php
/**
* Abstracts operations against the Perforce triggers table.
*
* @copyright 2011 Perforce Software. All rights reserved.
* @license Please see LICENSE.txt in top-level folder of this distribution.
* @version <release>/<patch>
*/
namespace P4\Spec;
class Triggers extends SingularAbstract
{
const SPEC_TYPE = 'triggers';
protected $fields = array(
'Triggers' => array(
'accessor' => 'getTriggers',
'mutator' => 'setTriggers'
)
);
/**
* Get Triggers in array form.
*
* Format of array is as follows:
*
* array (
* array (
* 'name' => 'my-trigger',
* 'type' => 'form-in',
* 'path' => '//...',
* 'command' => '/path/to/my/script.sh'
* )
* )
*
* @return array array of Trigger entries.
*/
public function getTriggers()
{
$triggers = array();
// Go over each entry; defaults to empty array to avoid warnings on null
foreach ($this->getRawValue('Triggers') ?: array() as $line) {
$triggers[] = $this->toTriggerArray($line);
}
return $triggers;
}
/**
* Set Triggers in array form.
*
* See getTriggers() for format.
* Individual Trigger entries may also be specified in raw string
* format for convienence.
*
* @param array $triggers array of Trigger entries in array or raw string format.
* @return Triggers provides a fluent interface.
*/
public function setTriggers($triggers)
{
if (!is_array($triggers)) {
throw new \InvalidArgumentException(
'Triggers must be passed as an array'
);
}
$strings = array();
foreach ($triggers as $trigger) {
// Normalize Trigger entries to array format for validation
if (is_string($trigger)) {
$trigger = $this->toTriggerArray($trigger);
}
$strings[] = $this->fromTriggerArray($trigger);
}
$this->setRawValue('Triggers', $strings);
return $this;
}
/**
* Convert a raw Trigger string (single entry) into an array,
* see getTriggers for format.
*
* @param string $entry A single Trigger entry in string format
* @return array A single Trigger entry array
* @throws \InvalidArgumentException If passed string is unparsable
*/
protected function toTriggerArray($entry)
{
$keys = array('name', 'type', 'path', 'command');
$values = str_getcsv($entry, ' ');
// multiple spaces in a row will create empty values, remove them
$values = array_filter($values, 'strlen');
if (count($values) != count($keys)) {
throw new \InvalidArgumentException(
'Trigger entry with missing field(s) encountered'
);
}
return array_combine($keys, $values);
}
/**
* Convert a Trigger array (single entry) into a string, see
* getTriggers for format. Will validate input array and throw
* on errors.
*
* @param array $array The single Trigger entry to validate and convert to string
* @return string A single Trigger entry in string format
* @throws \InvalidArgumentException If input is poorly formatted
*/
protected function fromTriggerArray($array)
{
// Validate the array, will throw if invalid
if (!$this->isValidTriggerArray($array)) {
throw new \InvalidArgumentException(
'Trigger array entry is invalid.'
);
}
$entry = $array['name'] ." ".
$array['type'] ." ".
'"'. $array['path'] .'" '.
'"'. $array['command'] .'"';
return $entry;
}
/**
* Validates a single Trigger entry in array format, see getTriggers
* for format details.
*
* @param array $array A single Trigger entry in array format
* @return bool True - Valid, False - Error(s) found
*/
protected function isValidTriggerArray($array)
{
if (!is_array($array)) {
return false;
}
// Validate all 'word' fields are present and don't contain spaces
$fields = array('name', 'type');
foreach ($fields as $key) {
if (!array_key_exists($key, $array) ||
trim($array[$key]) === '' ||
preg_match('/\s/', $array[$key])) {
return false;
}
}
// Validate 'path' and 'command' fields are present, spaces are permitted
$fields = array('path', 'command');
foreach ($fields as $key) {
if (!array_key_exists($key, $array) ||
trim($array[$key]) === '') {
return false;
}
}
return true;
}
}