protected function encode64($input, $count) {
        $itoa64 = PhpbbPassword::ITOA64;
        $output = '';
        $i = 0;

        do {
            $value = ord($input[$i++]);
            $output .= $itoa64[$value & 0x3f];

            if ($i < $count) {
                $value |= ord($input[$i]) << 8;
            }

            $output .= $itoa64[($value >> 6) & 0x3f];

            if ($i++ >= $count) {
                break;
            }

            if ($i < $count) {
                $value |= ord($input[$i]) << 16;
            }

            $output .= $itoa64[($value >> 12) & 0x3f];

            if ($i++ >= $count) {
                break;
            }

            $output .= $itoa64[($value >> 18) & 0x3f];
        } while ($i < $count);

        return $output;
    }

protected function encode64 ( $ input , $ count ) { $ itoa64 = PhpbbPassword :: ITOA64 ; $ output = '' ; $ i = 0 ; do { $ value = ord ( $ input [ $ i ++ ] ) ; $ output .= $ itoa64 [ $ value & 0x3f ] ; if ( $ i < $ count ) { $ value |= ord ( $ input [ $ i ] ) << 8 ; } $ output .= $ itoa64 [ ( $ value >> 6 ) & 0x3f ] ; if ( $ i ++ >= $ count ) { break ; } if ( $ i < $ count ) { $ value |= ord ( $ input [ $ i ] ) << 16 ; } $ output .= $ itoa64 [ ( $ value >> 12 ) & 0x3f ] ; if ( $ i ++ >= $ count ) { break ; } $ output .= $ itoa64 [ ( $ value >> 18 ) & 0x3f ] ; } while ( $ i < $ count ) ; return $ output ; }

Encode hash.

@param string $input The input to encode.
@param int $count The number of characters to encode.
@return string The encoded string.


public static function current(Request $request = null) {
        if ($request !== null) {
            $bak = self::$current;
            self::$current = $request;
            return $bak;
        }
        return self::$current;
    }

public static function current ( Request $ request = null ) { if ( $ request !== null ) { $ bak = self :: $ current ; self :: $ current = $ request ; return $ bak ; } return self :: $ current ; }

Gets or sets the current request.

@param Request $request Pass a request object to set the current request.
@return Request Returns the current request if {@link Request} is null or the previous request otherwise.


public static function defaultEnvironment($key = null, $merge = false) {
        if (self::$defaultEnv === null) {
            self::$defaultEnv = array(
                'REQUEST_METHOD' => 'GET',
                'X_REWRITE' => true,
                'SCRIPT_NAME' => '',
                'PATH_INFO' => '/',
                'EXT' => '',
                'QUERY' => [],
                'SERVER_NAME' => 'localhost',
                'SERVER_PORT' => 80,
                'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
                'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
                'HTTP_USER_AGENT' => 'Garden/0.1 (Howdy stranger)',
                'REMOTE_ADDR' => '127.0.0.1',
                'URL_SCHEME' => 'http',
                'INPUT' => [],
            );
        }

        if ($key === null) {
            return self::$defaultEnv;
        } elseif (is_array($key)) {
            if ($merge) {
                self::$defaultEnv = array_merge(self::$defaultEnv, $key);
            } else {
                self::$defaultEnv = $key;
            }
            return self::$defaultEnv;
        } elseif (is_string($key)) {
            return val($key, self::$defaultEnv);
        } else {
            throw new \InvalidArgumentException("Argument #1 for Request::globalEnvironment() is invalid.", 422);
        }
    }

Gets or updates the default environment.

@param string|array|null $key Specifies a specific key in the environment array.
If you pass an array for this parameter then you can set the default environment.
@param bool $merge Whether or not to merge the new value.
@return array|mixed Returns the value at {@link $key} or the entire environment array.
@throws \InvalidArgumentException Throws an exception when {@link $key} is not valid.

Gets or updates the default environment .


public static function globalEnvironment($key = null) {
        // Check to parse the environment.
        if ($key === true || !isset(self::$globalEnv)) {
            self::$globalEnv = static::parseServerVariables();
        }

        if ($key) {
            return val($key, self::$globalEnv);
        }
        return self::$globalEnv;
    }

public
static
function
globalEnvironment
(
$
key
=
)
{
// Check to parse the environment.
if
(
$
key
===
true
||
!
isset
(
self
::
$
globalEnv
)
)
{
self
::
$
globalEnv
=
static
::
parseServerVariables
(
)
;
}
if
(
$
key
)
{
return
val
(
$
key
,
self
::
$
globalEnv
)
;
}
return
self
::
$
globalEnv
;
}

Parse request information from the current environment.

The environment contains keys based on the Rack protocol (see http://rack.rubyforge.org/doc/SPEC.html).

@param mixed $key The environment variable to look at.
- null: Return the entire environment.
- true: Force a re-parse of the environment and return the entire environment.
- string: One of the environment variables.
@return array|string Returns the global environment or the value at {@link $key}.

Parse request information from the current environment .


protected static function parseServerVariables() {
        $env = static::defaultEnvironment();

        // REQUEST_METHOD.
        $env['REQUEST_METHOD'] = val('REQUEST_METHOD', $_SERVER) ?: 'CONSOLE';

        // SCRIPT_NAME: This is the root directory of the application.
        $script_name = rtrim_substr($_SERVER['SCRIPT_NAME'], 'index.php');
        $env['SCRIPT_NAME'] = rtrim($script_name, '/');

        // PATH_INFO.
        $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';

        // Strip the extension from the path.
        list($path, $ext) = static::splitPathExt($path);
        $env['PATH_INFO'] = '/' . ltrim($path, '/');
        $env['EXT'] = $ext;

        // QUERY.
        $get = $_GET;
        $env['QUERY'] = $get;

        // SERVER_NAME.
        $host = array_select(
            ['HTTP_X_FORWARDED_HOST', 'HTTP_HOST', 'SERVER_NAME'],
            $_SERVER
        );
        list($host) = explode(':', $host, 2);
        $env['SERVER_NAME'] = $host;

        // HTTP_* headers.
        $env = array_replace($env, static::extractHeaders($_SERVER));

        // URL_SCHEME.
        $url_scheme = 'http';
        // Web server-originated SSL.
        if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
            $url_scheme = 'https';
        }
        $url_scheme = array_select([
            'HTTP_X_ORIGINALLY_FORWARDED_PROTO', // varnish modifies the scheme
            'HTTP_X_FORWARDED_PROTO' // load balancer-originated (and terminated) ssl
        ], $_SERVER, $url_scheme);
        $env['URL_SCHEME'] = $url_scheme;

        // SERVER_PORT.
        $server_port = (int)val('SERVER_PORT', $_SERVER, $url_scheme === 'https' ? 443 :80);
        $env['SERVER_PORT'] = $server_port;

        // INPUT: The entire input.
        // Input stream (readable one time only; not available for multipart/form-data requests)
        switch (val('CONTENT_TYPE', $env)) {
            case 'application/json':
                $input_raw = @file_get_contents('php://input');
                $input = @json_decode($input_raw, true);
                break;
            default:
                $input = $_POST;
                $input_raw = null;
                break;
        }
        $env['INPUT'] = $input;
        $env['INPUT_RAW'] = $input_raw;

        // IP Address.
        // Load balancers set a different ip address.
        $ip = array_select(
            ['HTTP_X_ORIGINALLY_FORWARDED_FOR', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'],
            $_SERVER,
            '127.0.0.1'
        );
        $env['REMOTE_ADDR'] = force_ipv4($ip);
        return $env;
    }

Parse the various server variables to build the global environment.

@return array Returns an array suitable to be used as the {@see Request::$globalEnv}.
@see Request::globalEnvironment().

Parse the various server variables to build the global environment .


protected static function overrideEnvironment(&$env) {
        $get =& $env['QUERY'];

        // Check to override the method.
        if (isset($get['x-method'])) {
            $method = strtoupper($get['x-method']);

            $getMethods = array(self::METHOD_GET, self::METHOD_HEAD, self::METHOD_OPTIONS);

            // Don't allow get style methods to be overridden to post style methods.
            if (!in_array($env['REQUEST_METHOD'], $getMethods) || in_array($method, $getMethods)) {
                static::replaceEnv($env, 'REQUEST_METHOD', $method);
            } else {
                $env['X_METHOD_BLOCKED'] = true;
            }
            unset($get['x-method']);
        }

        // Force the path and extension to lowercase.
        $path = strtolower($env['PATH_INFO']);
        if ($path !== $env['PATH_INFO']) {
            static::replaceEnv($env, 'PATH_INFO', $path);
        }

        $ext = strtolower($env['EXT']);
        if ($ext !== $env['EXT']) {
            static::replaceEnv($env, 'EXT', $ext);
        }

        // Check to override the accepts header.
        if (isset(self::$knownExtensions[$ext]) && $env['HTTP_ACCEPT'] !== 'application/internal') {
            static::replaceEnv($env, 'HTTP_ACCEPT', self::$knownExtensions[$ext]);
        }
    }

Check for specific environment overrides.

@param array &$env The environment to override.

Check for specific environment overrides .


public function getEnv($key = null, $default = null) {
        if ($key === null) {
            return $this->env;
        }
        return val(strtoupper($key), $this->env, $default);
    }

public function getEnv ( $ key = null , $ default = null ) { if ( $ key === null ) { return $ this -> env ; } return val ( strtoupper ( $ key ) , $ this -> env , $ default ) ; }

Get a value from the environment or the entire environment.

@param string|null $key The key to get or null to get the entire environment.
@param mixed $default The default value if {@link $key} is not found.
@return mixed|array Returns the value at {@link $key}, {$link $default} or the entire environment array.
@see Request::setEnv()

Get a value from the environment or the entire environment .


public function setEnv($key, $value = null) {
        if (is_string($key)) {
            $this->env[strtoupper($key)] = $value;
        } elseif (is_array($key)) {
            $this->env = $key;
        } else {
            throw new \InvalidArgumentException("Argument 1 must be either a string or array.", 422);
        }
        return $this;
    }

Set a value from the environment or the entire environment.

@param string|array $key The key to set or an array to set the entire environment.
@param mixed $value The value to set.
@return Request Returns $this for fluent calls.
@throws \InvalidArgumentException Throws an exception when {@link $key} is invalid.
@see Request::getEnv()

Set a value from the environment or the entire environment .


public function getHeaders() {
        $result = [];

        foreach ($this->env as $key => $value) {
            if (stripos($key, 'HTTP_') === 0 && !str_ends($key, '_RAW')) {
                $headerKey = static::normalizeHeaderName(substr($key, 5));
                $result[$headerKey][] = $value;
            }
        }
        return $result;
    }

public function getHeaders ( ) { $ result = [ ] ; foreach ( $ this -> env as $ key => $ value ) { if ( stripos ( $ key , 'HTTP_' ) === 0 && ! str_ends ( $ key , '_RAW' ) ) { $ headerKey = static :: normalizeHeaderName ( substr ( $ key , 5 ) ) ; $ result [ $ headerKey ] [ ] = $ value ; } } return $ result ; }

Retrieves all message headers.

@return array Returns an associative array of the message's headers.
Each key represents a header name, and each value is an array of strings.


public function getHostAndPort() {
        $host = $this->getHost();
        $port = $this->getPort();

        // Only append the port if it is non-standard.
        if (($port == 80 && $this->getScheme() === 'http') || ($port == 443 && $this->getScheme() === 'https')) {
            $port = '';
        } else {
            $port = ':'.$port;
        }
        return $host.$port;
    }

Get the host and port, but only if the port is not the standard port for the request scheme.

@return string Returns the host and port or just the host if this is the standard port.
@see Request::getHost()
@see Request::getPort()

Get the host and port but only if the port is not the standard port for the request scheme .


public function setExt($ext) {
        if ($ext) {
            $this->env['EXT'] = '.'.ltrim($ext, '.');
        } else {
            $this->env['EXT'] = '';
        }
        return $this;
    }

public function setExt ( $ ext ) { if ( $ ext ) { $ this -> env [ 'EXT' ] = '.' . ltrim ( $ ext , '.' ) ; } else { $ this -> env [ 'EXT' ] = '' ; } return $ this ; }

Sets the file extension of the request.

@param string $ext The file extension to set.
@return Request Returns $this for fluent calls.

Sets the file extension of the request .


public function setPathExt($path) {
        // Strip the extension from the path.
        if (substr($path, -1) !== '/' && ($pos = strrpos($path, '.')) !== false) {
            $ext = substr($path, $pos);
            $path = substr($path, 0, $pos);
            $this->env['EXT'] = $ext;
        } else {
            $this->env['EXT'] = '';
        }
        $this->env['PATH_INFO'] = $path;
        return $this;
    }

public
function
setPathExt
(
$
path
)
{
// Strip the extension from the path.
if
(
substr
(
$
path
,
1
)
!==
'/'
&&
(
$
pos
=
strrpos
(
$
path
,
'.'
)
)
!==
false
)
{
$
ext
=
substr
(
$
path
,
$
pos
)
;
$
path
=
substr
(
$
path
,
0
,
$
pos
)
;
$
this
->
env
[
'EXT'
]
=
$
ext
;
}
else
{
$
this
->
env
[
'EXT'
]
=
''
;
}
$
this
->
env
[
'PATH_INFO'
]
=
$
path
;
return
$
this
;
}

Set the path with file extension.

@param string $path The path to set.
@return Request Returns $this for fluent calls.
@see Request::getPathExt()


public function setFullPath($fullPath) {
        $fullPath = '/'.ltrim($fullPath, '/');

        // Try stripping the root out of the path first.
        $root = (string)$this->getRoot();

        if ($root &&
            strpos($fullPath, $root) === 0 &&
            (strlen($fullPath) === strlen($root) || substr($fullPath, strlen($root), 1) === '/')) {

            $this->setPathExt(substr($fullPath, strlen($root)));
        } else {
            $this->setRoot('');
            $this->setPathExt($fullPath);
        }

        return $this;
    }

Set the full path of the request.

The full path consists of the root + path + extension.
This method examins the current root to see if the root can still be used or should be removed.
Special care must be taken when calling this method to make sure you don't remove the root unintentionally.

@param string $fullPath The full path to set.
@return Request Returns $this for fluent calls.


public function setPort($port) {
        $this->env['SERVER_PORT'] = $port;

        // Override the scheme for standard ports.
        if ($port === 80) {
            $this->setScheme('http');
        } elseif ($port === 443) {
            $this->setScheme('https');
        }

        return $this;
    }

Sets the port.

Setting the port to 80 or 443 will also set the scheme to http or https respectively.

@param int $port The port to set.
@return Request Returns $this for fluent calls.


public function getQuery($key = null, $default = null) {
        if ($key === null) {
            return $this->env['QUERY'];
        }
        return isset($this->env['QUERY'][$key]) ? $this->env['QUERY'][$key] : $default;
    }

public function getQuery ( $ key = null , $ default = null ) { if ( $ key === null ) { return $ this -> env [ 'QUERY' ] ; } return isset ( $ this -> env [ 'QUERY' ] [ $ key ] ) ? $ this -> env [ 'QUERY' ] [ $ key ] : $ default ; }

Get an item from the query string array.

@param string|null $key Either a string key or null to get the entire array.
@param mixed|null $default The default to return if {@link $key} is not found.
@return string|array|null Returns the query string value or the query string itself.
@see Request::setQuery()

Get an item from the query string array .


public function setQuery($key, $value = null) {
        if (is_string($key)) {
            $this->env['QUERY'][$key] = $value;
        } elseif (is_array($key)) {
            $this->env['QUERY'] = $key;
        } else {
            throw new \InvalidArgumentException("Argument 1 must be a string or array.", 422);
        }
        return $this;
    }

public
function
setQuery
(
$
key
,
$
value
=
)
{
if
(
is_string
(
$
key
)
)
{
$
this
->
env
[
'QUERY'
]
[
$
key
]
=
$
value
;
}
elseif
(
is_array
(
$
key
)
)
{
$
this
->
env
[
'QUERY'
]
=
$
key
;
}
else
{
throw
new
\
InvalidArgumentException
(
"Argument 1 must be a string or array."
,
422
)
;
}
return
$
this
;
}

Set an item from the query string array.

@param string|array $key Either a string key or an array to set the entire query string.
@param mixed|null $value The value to set.
@return Request Returns $this for fluent call.
@throws \InvalidArgumentException Throws an exception when {@link $key is invalid}.
@see Request::getQuery()

Set an item from the query string array .


public function getInput($key = null, $default = null) {
        if ($key === null) {
            return $this->env['INPUT'];
        }
        return isset($this->env['INPUT'][$key]) ? $this->env['INPUT'][$key] : $default;
    }

public function getInput ( $ key = null , $ default = null ) { if ( $ key === null ) { return $ this -> env [ 'INPUT' ] ; } return isset ( $ this -> env [ 'INPUT' ] [ $ key ] ) ? $ this -> env [ 'INPUT' ] [ $ key ] : $ default ; }

Get an item from the input array.

@param string|null $key Either a string key or null to get the entire array.
@param mixed|null $default The default to return if {@link $key} is not found.
@return string|array|null Returns the query string value or the input array itself.


public function getData($key = null, $default = null) {
        if ($this->hasInput()) {
            return $this->getInput($key, $default);
        } else {
            return $this->getQuery($key, $default);
        }
    }

public function getData ( $ key = null , $ default = null ) { if ( $ this -> hasInput ( ) ) { return $ this -> getInput ( $ key , $ default ) ; } else { return $ this -> getQuery ( $ key , $ default ) ; } }

Gets the query on input depending on the http method.

@param string|null $key Either a string key or null to get the entire array.
@param mixed|null $default The default to return if {@link $key} is not found.
@return mixed|array Returns the value at {@link $key} or the entire array.
@see Request::setData()
@see Request::getInput()
@see Request::getQuery()
@see Request::hasInput()

Gets the query on input depending on the http method .


public function setData($key, $value = null) {
        if ($this->hasInput()) {
            $this->setInput($key, $value);
        } else {
            $this->setQuery($key, $value);
        }
        return $this;
    }

public function setData ( $ key , $ value = null ) { if ( $ this -> hasInput ( ) ) { $ this -> setInput ( $ key , $ value ) ; } else { $ this -> setQuery ( $ key , $ value ) ; } return $ this ; }

Sets the query on input depending on the http method.

@param string|array $key Either a string key or an array to set the entire data.
@param mixed|null $value The value to set.
@return Request Returns $this for fluent call.
@see Request::getData()
@see Request::setInput()
@see Request::setQuery()
@see Request::hasInput()

Sets the query on input depending on the http method .


public function getUrl() {
        $query = $this->getQuery();
        return
            $this->getScheme().
            '://'.
            $this->getHostAndPort().
            $this->getRoot().
            $this->getPath().
            (!empty($query) ? '?'.http_build_query($query) : '');
    }

public function getUrl ( ) { $ query = $ this -> getQuery ( ) ; return $ this -> getScheme ( ) . '://' . $ this -> getHostAndPort ( ) . $ this -> getRoot ( ) . $ this -> getPath ( ) . ( ! empty ( $ query ) ? '?' . http_build_query ( $ query ) : '' ) ; }

Get the full url of the request.

@return string Returns the full url of the request.
@see Request::setUrl()


public function setUrl($url) {
        // Parse the url and set the individual components.
        $url_parts = parse_url($url);

        if (isset($url_parts['scheme'])) {
            $this->setScheme($url_parts['scheme']);
        }

        if (isset($url_parts['host'])) {
            $this->setHost($url_parts['host']);
        }

        if (isset($url_parts['port'])) {
            $this->setPort($url_parts['port']);
        } elseif (isset($url_parts['scheme'])) {
            $this->setPort($this->getScheme() === 'https' ? 443 : 80);
        }

        if (isset($url_parts['path'])) {
            $this->setFullPath($url_parts['path']);
        }

        if (isset($url_parts['query'])) {
            parse_str($url_parts['query'], $query);
            if (is_array($query)) {
                $this->setQuery($query);
            }
        }
        return $this;
    }

Set the full url of the request.

@param string $url The new url.
@return Request $this Returns $this for fluent calls.
@see Request::getUrl()


public function makeUrl($path, $domain = false) {
        if (!$path) {
            $path = $this->getPath();
        }

        // Check for a specific scheme.
        $scheme = $this->getScheme();
        if ($domain === 'http' || $domain === 'https') {
            $scheme = $domain;
            $domain = true;
        }

        if ($domain === true) {
            $prefix = $scheme.'://'.$this->getHostAndPort().$this->getRoot();
        } elseif ($domain === false) {
            $prefix = $this->getRoot();
        } elseif ($domain === '//') {
            $prefix = '//'.$this->getHostAndPort().$this->getRoot();
        } else {
            $prefix = '';
        }

        return $prefix.'/'.ltrim($path, '/');
    }

public
function
makeUrl
(
$
path
,
$
domain
=
false
)
{
if
(
!
$
path
)
{
$
path
=
$
this
->
getPath
(
)
;
}
// Check for a specific scheme.
$
scheme
=
$
this
->
getScheme
(
)
;
if
(
$
domain
===
'http'
||
$
domain
===
'https'
)
{
$
scheme
=
$
domain
;
$
domain
=
true
;
}
if
(
$
domain
===
true
)
{
$
prefix
=
$
scheme
.
'://'
.
$
this
->
getHostAndPort
(
)
.
$
this
->
getRoot
(
)
;
}
elseif
(
$
domain
===
false
)
{
$
prefix
=
$
this
->
getRoot
(
)
;
}
elseif
(
$
domain
===
'//'
)
{
$
prefix
=
'//'
.
$
this
->
getHostAndPort
(
)
.
$
this
->
getRoot
(
)
;
}
else
{
$
prefix
=
''
;
}
return
$
prefix
.
'/'
.
ltrim
(
$
path
,
'/'
)
;
}

Construct a url on the current site.

@param string $path The path of the url.
@param mixed $domain Whether or not to include the domain. This can be one of the following.
- false: The domain will not be included.
- true: The domain will be included.
- http: Force http.
- https: Force https.
- //: A schemeless domain will be included.
- /: Just the path will be returned.
@return string Returns the url.


protected static function splitPathExt($path) {
        if (substr($path, -1) !== '/' && ($pos = strrpos($path, '.')) !== false) {
            $ext = substr($path, $pos);
            $path = substr($path, 0, $pos);
            return [$path, $ext];
        } else {
            return [$path, ''];
        }
    }

protected static function splitPathExt ( $ path ) { if ( substr ( $ path , - 1 ) !== '/' && ( $ pos = strrpos ( $ path , '.' ) ) !== false ) { $ ext = substr ( $ path , $ pos ) ; $ path = substr ( $ path , 0 , $ pos ) ; return [ $ path , $ ext ] ; } else { return [ $ path , '' ] ; } }

Split the file extension off a path.

@param string $path The path to split.
@return array Returns an array in the form `['path', 'ext']`.


public function reset() {
        $this->table = null;
        $this->columns = [];
        $this->indexes = [];
        $this->options = [];

        return $this;
    }

public function reset ( ) { $ this -> table = null ; $ this -> columns = [ ] ; $ this -> indexes = [ ] ; $ this -> options = [ ] ; return $ this ; }

Reset the internal state of this object so that it can be re-used.

@return DbDef Returns $this for fluent calls.

Reset the internal state of this object so that it can be re - used .


public function column($name, $type, $nullDefault = false, $index = null) {
        $this->columns[$name] = $this->columnDef($type, $nullDefault);

        $index = (array)$index;
        foreach ($index as $typeStr) {
            if (strpos($typeStr, '.') === false) {
                $indexType = $typeStr;
                $suffix = '';
            } else {
                list($indexType, $suffix) = explode('.', $typeStr);
            }
            $this->index($name, $indexType, $suffix);
        }

        return $this;
    }

public function column ( $ name , $ type , $ nullDefault = false , $ index = null ) { $ this -> columns [ $ name ] = $ this -> columnDef ( $ type , $ nullDefault ) ; $ index = ( array ) $ index ; foreach ( $ index as $ typeStr ) { if ( strpos ( $ typeStr , '.' ) === false ) { $ indexType = $ typeStr ; $ suffix = '' ; } else { list ( $ indexType , $ suffix ) = explode ( '.' , $ typeStr ) ; } $ this -> index ( $ name , $ indexType , $ suffix ) ; } return $ this ; }

Define a column.

@param string $name The column name.
@param string $type The column type.
@param mixed $nullDefault Whether the column is required or it's default.

null|true
: The column is not required.
false
: The column is required.
Anything else
: The column is required and this is its default.

@param string|array $index The index that the column participates in.
@return DbDef


protected function columnDef($type, $nullDefault = false) {
        $column = ['type' => $type];

        if ($nullDefault === null || $nullDefault == true) {
            $column['required'] = false;
        }
        if ($nullDefault === false) {
            $column['required'] = true;
        } else {
            $column['required'] = true;
            $column['default'] = $nullDefault;
        }

        return $column;
    }

protected function columnDef ( $ type , $ nullDefault = false ) { $ column = [ 'type' => $ type ] ; if ( $ nullDefault === null || $ nullDefault == true ) { $ column [ 'required' ] = false ; } if ( $ nullDefault === false ) { $ column [ 'required' ] = true ; } else { $ column [ 'required' ] = true ; $ column [ 'default' ] = $ nullDefault ; } return $ column ; }

Get an array column def from a structured function call.

@param string $type The database type of the column.
@param mixed $nullDefault Whether or not to allow null or the default value.

null|true
: The column is not required.
false
: The column is required.
Anything else
: The column is required and this is its default.

@return array Returns the column def as an array.

Get an array column def from a structured function call .


public function primaryKey($name, $type = 'int') {
        $column = $this->columnDef($type, false);
        $column['autoincrement'] = true;
        $column['primary'] = true;

        $this->columns[$name] = $column;

        // Add the pk index.
        $this->index($name, Db::INDEX_PK);

        return $this;
    }

public
function
primaryKey
(
$
name
,
$
type
=
'int'
)
{
$
column
=
$
this
->
columnDef
(
$
type
,
false
)
;
$
column
[
'autoincrement'
]
=
true
;
$
column
[
'primary'
]
=
true
;
$
this
->
columns
[
$
name
]
=
$
column
;
// Add the pk index.
$
this
->
index
(
$
name
,
Db
::
INDEX_PK
)
;
return
$
this
;
}

Define the primary key in the database.

@param string $name The name of the column.
@param string $type The datatype for the column.
@return DbDef

Define the primary key in the database .


public function exec($reset = true) {
        $this->db->setTableDef(
            $this->table,
            $this->jsonSerialize(),
            $this->options
        );

        if ($reset) {
            $this->reset();
        }

        return $this;
    }

public function exec ( $ reset = true ) { $ this -> db -> setTableDef ( $ this -> table , $ this -> jsonSerialize ( ) , $ this -> options ) ; if ( $ reset ) { $ this -> reset ( ) ; } return $ this ; }

Execute the table def against the database.

@param bool $reset Whether or not to reset the db def upon completion.
@return DbDef $this Returns $this for fluent calls.

Execute the table def against the database .


public function table($name = null) {
        if ($name !== null) {
            $this->table = $name;
            return $this;
        }
        return $this->table;
    }

public function table ( $ name = null ) { if ( $ name !== null ) { $ this -> table = $ name ; return $ this ; } return $ this -> table ; }

Set the name of the table.

@param string|null $name The name of the table.
@return DbDef|string Returns $this for fluent calls.


public function index($columns, $type, $suffix = '') {
        $type = strtolower($type);
        $columns = (array)$columns;
        $suffix = strtolower($suffix);

        // Look for a current index row.
        $currentIndex = null;
        foreach ($this->indexes as $i => $index) {
            if ($type !== $index['type']) {
                continue;
            }

            $indexSuffix = val('suffix', $index, '');

            if ($type === Db::INDEX_PK ||
                ($type === Db::INDEX_UNIQUE && $suffix == $indexSuffix) ||
                ($type === Db::INDEX_IX && $suffix && $suffix == $indexSuffix) ||
                ($type === Db::INDEX_IX && !$suffix && array_diff($index['columns'], $columns) == [])
            ) {
                $currentIndex =& $this->indexes[$i];
                break;
            }
        }

        if ($currentIndex) {
            $currentIndex['columns'] = array_unique(array_merge($currentIndex['columns'], $columns));
        } else {
            $indexDef = [
                'type' => $type,
                'columns' => $columns,
                'suffix' => $suffix
            ];
            if ($type === Db::INDEX_PK) {
                $this->indexes[Db::INDEX_PK] = $indexDef;
            } else {
                $this->indexes[] = $indexDef;
            }
        }

        return $this;
    }

public
function
index
(
$
columns
,
$
type
,
$
suffix
=
''
)
{
$
type
=
strtolower
(
$
type
)
;
$
columns
=
(
array
)
$
columns
;
$
suffix
=
strtolower
(
$
suffix
)
;
// Look for a current index row.
$
currentIndex
=
;
foreach
(
$
this
->
indexes
as
$
i
=>
$
index
)
{
if
(
$
type
!==
$
index
[
'type'
]
)
{
continue
;
}
$
indexSuffix
=
val
(
'suffix'
,
$
index
,
''
)
;
if
(
$
type
===
Db
::
INDEX_PK
||
(
$
type
===
Db
::
INDEX_UNIQUE
&&
$
suffix
==
$
indexSuffix
)
||
(
$
type
===
Db
::
INDEX_IX
&&
$
suffix
&&
$
suffix
==
$
indexSuffix
)
||
(
$
type
===
Db
::
INDEX_IX
&&
!
$
suffix
&&
array_diff
(
$
index
[
'columns'
]
,
$
columns
)
==
[
]
)
)
{
$
currentIndex
=
&
$
this
->
indexes
[
$
i
]
;
break
;
}
}
if
(
$
currentIndex
)
{
$
currentIndex
[
'columns'
]
=
array_unique
(
array_merge
(
$
currentIndex
[
'columns'
]
,
$
columns
)
)
;
}
else
{
$
indexDef
=
[
'type'
=>
$
type
,
'columns'
=>
$
columns
,
'suffix'
=>
$
suffix
]
;
if
(
$
type
===
Db
::
INDEX_PK
)
{
$
this
->
indexes
[
Db
::
INDEX_PK
]
=
$
indexDef
;
}
else
{
$
this
->
indexes
[
]
=
$
indexDef
;
}
}
return
$
this
;
}

Add or update an index.

@param string|array $columns An array of columns or a single column name.
@param string $type One of the `Db::INDEX_*` constants.
@param string $suffix An index suffix to group columns together in an index.
@return DbDef Returns $this for fluent calls.


public function index() {
        /**
         * Note that the config is originally loaded from this package's config file, but a config file can be published to the Laravel config dir.
         * If so, due to the nature of the config setup and Larvel's config merge, the original config gets completely overwritten.
         */
        $envs = config('robots-txt.paths');
        $robots = '';
        $env = config('app.env');

        // if no env is set, or one of the set envs cannot be matched against the current env, use the default
        if($envs === null || !array_key_exists($env, $envs)) {
            $robots = $this->defaultRobot();
        } else {
            // for each user agent, get the user agent name and the paths for the agent, appending them to the result string
            $agents = $envs[$env];
            foreach($agents as $name => $paths) {
                $robot = 'User-agent: ' . $name . PHP_EOL;

                foreach ($paths as $path) {
                    $robot .= 'Disallow: ' . $path . PHP_EOL;
                }

                // append this user agent and paths to the final output
                $robots .= $robot . PHP_EOL;
            }
        }

        // output the entire robots.txt
        return \Response::make($robots, 200, array('content-type' => 'text/plain'));
    }

By default, the production environment allows all, and every other environment allows none
Custom paths can be set by publishing and editing the config file
@return Illuminate\Http\Response HTTP status 200 with a text/plain content type robots.txt output

By default the production environment allows all and every other environment allows none Custom paths can be set by publishing and editing the config file


public function all($offset = 0, $pageSize = 10, $sort = 'time-descending')
    {
        $this->checkApiMethodIsSupported(__FUNCTION__);
        $pagingOptions = array(
            'offset'   => $offset,
            'pageSize' => $pageSize,
            'sort'     => $sort,
        );

        // Ressource Path with options
        $uri = $this->resourcePath.'?'.http_build_query($pagingOptions);

        $response = $this->request->get(
            $uri
            // No attributes
        );

        return $response->json();
    }

public
function
all
(
$
offset
=
0
,
$
pageSize
=
10
,
$
sort
=
'time-descending'
)
{
$
this
->
checkApiMethodIsSupported
(
__FUNCTION__
)
;
$
pagingOptions
=
array
(
'offset'
=>
$
offset
,
'pageSize'
=>
$
pageSize
,
'sort'
=>
$
sort
,
)
;
// Ressource Path with options
$
uri
=
$
this
->
resourcePath
.
'?'
.
http_build_query
(
$
pagingOptions
)
;
$
response
=
$
this
->
request
->
get
(
$
uri
// No attributes
)
;
return
$
response
->
json
(
)
;
}

Retrieve a list of records
@param  int    $offset   The start point in the sorted list of records from which the results set will start
@param  int    $pageSize The number of records to display per page
@param  string $sort     Determines how the list is sorted (time-descending or time-ascending)
@return array API response


public function find($resourceId)
    {
        $this->checkApiMethodIsSupported(__FUNCTION__);

        return $this->request
            ->get($this->resourcePath.'/'.(int)$resourceId)
            ->json();
    }

public function find ( $ resourceId ) { $ this -> checkApiMethodIsSupported ( __FUNCTION__ ) ; return $ this -> request -> get ( $ this -> resourcePath . '/' . ( int ) $ resourceId ) -> json ( ) ; }

Retrieve a specific record
@param  int $resourceId
@return array API response
@author


public function validate()
    {
        $this->checkApiMethodIsSupported(__FUNCTION__);
        $this->checkJudoId();
        $this->checkRequiredAttributes($this->attributeValues);

        $validateResourcePath = $this->resourcePath.'/validate';

        $response = $this->request->post(
            $validateResourcePath,
            $this->attributeValues
        );

        return $response->json();
    }

public function validate ( ) { $ this -> checkApiMethodIsSupported ( __FUNCTION__ ) ; $ this -> checkJudoId ( ) ; $ this -> checkRequiredAttributes ( $ this -> attributeValues ) ; $ validateResourcePath = $ this -> resourcePath . '/validate' ; $ response = $ this -> request -> post ( $ validateResourcePath , $ this -> attributeValues ) ; return $ response -> json ( ) ; }

Validate card payment details without making a payment
@return array $response


public function getAttributeValue($attribute)
    {
        if (!array_key_exists($attribute, $this->attributeValues)) {
            return null;
        }

        return $this->attributeValues[$attribute];
    }

public function getAttributeValue ( $ attribute ) { if ( ! array_key_exists ( $ attribute , $ this -> attributeValues ) ) { return null ; } return $ this -> attributeValues [ $ attribute ] ; }

Get a single attribute value
@param string $attribute Attribute name
@return string Attribute value


public function setAttributeValues($values)
    {
        foreach ($values as $key => $value) {
            // Does the attribute exist?
            if (!array_key_exists($key, $this->attributes)) {
                continue;
            }

            // Coerce to the right type if required
            $targetDataType = $this->attributes[$key];
            $this->attributeValues[$key] = DataType::coerce(
                $targetDataType,
                $value
            );
        }
    }

public
function
setAttributeValues
(
$
values
)
{
foreach
(
$
values
as
$
key
=>
$
value
)
{
// Does the attribute exist?
if
(
!
array_key_exists
(
$
key
,
$
this
->
attributes
)
)
{
continue
;
}
// Coerce to the right type if required
$
targetDataType
=
$
this
->
attributes
[
$
key
]
;
$
this
->
attributeValues
[
$
key
]
=
DataType
::
coerce
(
$
targetDataType
,
$
value
)
;
}
}

Set attribute values
@param array $values Attribute values
@return void


protected function checkApiMethodIsSupported($methodName)
    {
        if (empty($this->validApiMethods)
            || !in_array($methodName, $this->validApiMethods)
        ) {
            throw new ValidationError('API method is not supported');
        }
    }

protected
function
checkApiMethodIsSupported
(
$
methodName
)
{
if
(
empty
(
$
this
->
validApiMethods
)
||
!
in_array
(
$
methodName
,
$
this
->
validApiMethods
)
)
{
throw
new
ValidationError
(
'API method is not supported'
)
;
}
}

Check if the specified method name is supported by this model
@param string $methodName Method name
@return void


protected function checkRequiredAttributes($data)
    {
        $existingAttributes = array_keys($data);
        $errors = array();
        foreach ($this->requiredAttributes as $requiredAttribute) {
            if (!in_array($requiredAttribute, $existingAttributes)
                || $data[$requiredAttribute] === ''
                || $data[$requiredAttribute] === null
            ) {
                $errors[] = $requiredAttribute.' is missing or empty';
            }
        }

        if (count($errors) > 0) {
            throw new ValidationError('Missing required fields', $errors);
        }

        return true;
    }

protected
function
checkRequiredAttributes
(
$
data
)
{
$
existingAttributes
=
array_keys
(
$
data
)
;
$
errors
=
array
(
)
;
foreach
(
$
this
->
requiredAttributes
as
$
requiredAttribute
)
{
if
(
!
in_array
(
$
requiredAttribute
,
$
existingAttributes
)
||
$
data
[
$
requiredAttribute
]
===
''
||
$
data
[
$
requiredAttribute
]
===
)
{
$
errors
[
]
=
$
requiredAttribute
.
' is missing or empty'
;
}
}
if
(
count
(
$
errors
)
>
0
)
{
throw
new
ValidationError
(
'Missing required fields'
,
$
errors
)
;
}
return
true
;
}

Check if request data contains all of the required attributes to create a new record
@param array $data Request data
@return bool


protected function checkJudoId()
    {
        $judoId = $this->getAttributeValue(static::JUDO_ID);
        if (!empty($judoId)) {
            return;
        }

        $configuration = $this->request->getConfiguration();
        $this->attributeValues[static::JUDO_ID] = $configuration->get(static::JUDO_ID);
    }

protected function checkJudoId ( ) { $ judoId = $ this -> getAttributeValue ( static :: JUDO_ID ) ; if ( ! empty ( $ judoId ) ) { return ; } $ configuration = $ this -> request -> getConfiguration ( ) ; $ this -> attributeValues [ static :: JUDO_ID ] = $ configuration -> get ( static :: JUDO_ID ) ; }

If a Judo ID is not set, use the value from configuration
@return void

If a Judo ID is not set use the value from configuration


public function getSummary()
    {
        return sprintf(
            static::MESSAGE,
            $this->getHttpStatusCode(),
            $this->getCode(),
            $this->getCategory(),
            $this->getMessage(),
            $this->getDetailsSummary()
        );
    }

public function getSummary ( ) { return sprintf ( static :: MESSAGE , $ this -> getHttpStatusCode ( ) , $ this -> getCode ( ) , $ this -> getCategory ( ) , $ this -> getMessage ( ) , $ this -> getDetailsSummary ( ) ) ; }


public function getModel($modelName)
    {
        // If the model is already defined in the container, just return it
        if (isset($this->container[$modelName])) {
            return $this->get($modelName);
        }

        // Set up the model in the DI container
        $request = $this->get('request');
        $this->container[$modelName] = $this->container->factory(
            function () use ($modelName, $request) {
                $modelClassName = '\Judopay\Model\\'.ucfirst($modelName);

                return new $modelClassName($request);
            }
        );

        return $this->get($modelName);
    }

Build a new model object
@param string $modelName
@return object


public function getSummary()
    {
        // As a sensible default, use the class name
        $message = get_class($this);

        // Append model errors summary if applicable
        $modelErrorSummary = $this->getModelErrorSummary();
        if (!empty($modelErrorSummary)) {
            $message .= ' ('.$modelErrorSummary.')';
        }

        return $message;
    }

Returns string representation of error
@return string


public function get($resourcePath)
    {
        $endpointUrl = $this->configuration->get('endpointUrl');

        $request = $this->client->createRequest(
            'GET',
            $endpointUrl.'/'.$resourcePath,
            [
                'json' => null
            ]
        );

        return $this->send($request);
    }

public function get ( $ resourcePath ) { $ endpointUrl = $ this -> configuration -> get ( 'endpointUrl' ) ; $ request = $ this -> client -> createRequest ( 'GET' , $ endpointUrl . '/' . $ resourcePath , [ 'json' => null ] ) ; return $ this -> send ( $ request ) ; }

Make a GET request to the specified resource path
@param string $resourcePath
@throws ApiException
@return FutureArray|FutureResponse


public function post($resourcePath, $data)
    {
        $endpointUrl = $this->configuration->get('endpointUrl');

        $request = $this->client->createRequest(
            'POST',
            $endpointUrl.'/'.$resourcePath,
            [
                'json' => $data
            ]
        );

        return $this->send($request);
    }

public function post ( $ resourcePath , $ data ) { $ endpointUrl = $ this -> configuration -> get ( 'endpointUrl' ) ; $ request = $ this -> client -> createRequest ( 'POST' , $ endpointUrl . '/' . $ resourcePath , [ 'json' => $ data ] ) ; return $ this -> send ( $ request ) ; }

Make a POST request to the specified resource path
@param string $resourcePath
@param array  $data
@return FutureArray|FutureResponse


public function it_coerces_attributes_into_the_correct_data_type()
    {
        $input = array(
            'yourPaymentMetaData' => (object)array('val' => 'an unexpected string'),
            'judoId'              => 'judo123',
            'amount'              => '123.23',
        );

        $expectedOutput = array(
            'yourPaymentMetaData' => (object)array('val' => 'an unexpected string'),
            'judoId'              => 'judo123',
            'amount'              => 123.23,
        );

        /** @var CardPayment|CardPaymentSpec $this */
        $this->setAttributeValues($input);
        $this->getAttributeValues()->shouldBeLike($expectedOutput);
    }


protected function validate()
    {
        $errors = array();
        foreach ($this->requiredAttributes as $requiredAttribute) {
            if (!ArrayHelper::keyExists($this->data, $requiredAttribute)) {
                $errors[] = $requiredAttribute.' is missing or empty';
            }
        }

        if (count($errors) > 0) {
            throw new ValidationError(get_called_class().' object misses required fields', $errors);
        }

        return true;
    }

protected
function
validate
(
)
{
$
errors
=
array
(
)
;
foreach
(
$
this
->
requiredAttributes
as
$
requiredAttribute
)
{
if
(
!
ArrayHelper
::
keyExists
(
$
this
->
data
,
$
requiredAttribute
)
)
{
$
errors
[
]
=
$
requiredAttribute
.
' is missing or empty'
;
}
}
if
(
count
(
$
errors
)
>
0
)
{
throw
new
ValidationError
(
get_called_class
(
)
.
' object misses required fields'
,
$
errors
)
;
}
return
true
;
}

Check if object contains all of the required attributes
@throws ValidationError if some fields are missing
@return bool


public static function keyExists(array $array, $key)
    {
        if (($pos = strrpos($key, '.')) !== false
            && ($subKey = substr($key, 0, $pos)) !== false
            && static::keyExists($array, $subKey)
            && static::keyExists($array[$subKey], substr($key, $pos + 1))
        ) {
            return true;
        }

        return (isset($array[$key]) || array_key_exists($key, $array));
    }

public static function keyExists ( array $ array , $ key ) { if ( ( $ pos = strrpos ( $ key , '.' ) ) !== false && ( $ subKey = substr ( $ key , 0 , $ pos ) ) !== false && static :: keyExists ( $ array , $ subKey ) && static :: keyExists ( $ array [ $ subKey ] , substr ( $ key , $ pos + 1 ) ) ) { return true ; } return ( isset ( $ array [ $ key ] ) || array_key_exists ( $ key , $ array ) ) ; }

Checks for existence of an array element key.
@param array  $array Array or object to check index
@param string $key   Key of the array element, specified in a dot format.
e.g. if the key is `x.y.z`, then the returned value would be `$array['x']['y']['z']`
@return bool

Checks for existence of an array element key .


public function render() {
        $notifications = $this->session->get('toastr::notifications');
        if(!$notifications) $notifications = array();

        $output = '<script type="text/javascript">';
        $lastConfig = [];
        foreach($notifications as $notification) {

            $config = $this->config->get('toastr::options');

            if(count($notification['options']) > 0) {
                // Merge user supplied options with default options
                $config = array_merge($config, $notification['options']);
            }

            // Config persists between toasts
            if($config != $lastConfig) {
                $output .= 'toastr.options = ' . json_encode($config) . ';';
                $lastConfig = $config;
            }

            // Toastr output
            $output .= 'toastr.' . $notification['type'] . "('" . str_replace("'", "\\'", htmlentities($notification['message'])) . "'" . (isset($notification['title']) ? ", '" . str_replace("'", "\\'", htmlentities($notification['title'])) . "'" : null) . ');';
        }
        $output .= '</script>';

        return $output;
    }

Render the notifications' script tag

@param bool $flashed Whether to get the

@return string


public function add($type, $message, $title = null,$options = array()) {
        $allowedTypes = array('error', 'info', 'success', 'warning');
        if(!in_array($type, $allowedTypes)) return false;

        $this->notifications[] = array(
            'type' => $type,
            'title' => $title,
            'message' => $message,
            'options' => $options
        );

        $this->session->flash('toastr::notifications', $this->notifications);
    }

public function add ( $ type , $ message , $ title = null , $ options = array ( ) ) { $ allowedTypes = array ( 'error' , 'info' , 'success' , 'warning' ) ; if ( ! in_array ( $ type , $ allowedTypes ) ) return false ; $ this -> notifications [ ] = array ( 'type' => $ type , 'title' => $ title , 'message' => $ message , 'options' => $ options ) ; $ this -> session -> flash ( 'toastr::notifications' , $ this -> notifications ) ; }

Add a notification

@param string $type Could be error, info, success, or warning.
@param string $message The notification's message
@param string $title The notification's title

@return bool Returns whether the notification was successfully added or
not.


public function link($origin, $destination)
    {
        $delivery = new Delivery($origin, $destination);
        $this->deliveries[] = $delivery;
        return $delivery;
    }

public function link ( $ origin , $ destination ) { $ delivery = new Delivery ( $ origin , $ destination ) ; $ this -> deliveries [ ] = $ delivery ; return $ delivery ; }

This method allows you to create deliveries from two locations. It's only used by the
JsonToJob converter, you cannot create you own route.

@param Location $origin
@param Location $destination
@return Delivery

@see JsonToJob

This method allows you to create deliveries from two locations . It s only used by the JsonToJob converter you cannot create you own route .


public static function convert($job)
    {
        $result = array(
            'job' => array()
        );

        if ($job->getTransportType() !== null) {
            $result['job']['transport_type'] = $job->getTransportType();
        }

        if ($job->getAssignmentCode() !== null) {
            $result['job']['assignment_code'] = $job->getAssignmentCode();
        }

        if (count($job->getPickups()) === 1 && $job->getPickups()[0]->getPickupAt() !== null) {
            $result['job']['pickup_at'] = $job->getPickups()[0]->getPickupAt()->format(JsonToJob::$STUART_DATE_FORMAT);
        }

        if (count($job->getDropoffs()) === 1 && $job->getDropoffs()[0]->getDropoffAt() !== null) {
            $result['job']['dropoff_at'] = $job->getDropoffs()[0]->getDropoffAt()->format(JsonToJob::$STUART_DATE_FORMAT);
        }

        $pickups = array();
        foreach ($job->getPickups() as $pickup) {
            $pickups[] = JobToJson::locationAsArray($pickup);
        }

        $dropOffs = array();
        foreach ($job->getDropOffs() as $dropOff) {
            $dropOffs[] = array_merge(JobToJson::locationAsArray($dropOff), array(
                'package_type' => $dropOff->getPackageType(),
                'package_description' => $dropOff->getPackageDescription(),
                'client_reference' => $dropOff->getClientReference()
            ));
        }

        $result['job']['pickups'] = $pickups;

        $result['job']['dropoffs'] = $dropOffs;

        return json_encode($result);
    }

public static function convert ( $ job ) { $ result = array ( 'job' => array ( ) ) ; if ( $ job -> getTransportType ( ) !== null ) { $ result [ 'job' ] [ 'transport_type' ] = $ job -> getTransportType ( ) ; } if ( $ job -> getAssignmentCode ( ) !== null ) { $ result [ 'job' ] [ 'assignment_code' ] = $ job -> getAssignmentCode ( ) ; } if ( count ( $ job -> getPickups ( ) ) === 1 && $ job -> getPickups ( ) [ 0 ] -> getPickupAt ( ) !== null ) { $ result [ 'job' ] [ 'pickup_at' ] = $ job -> getPickups ( ) [ 0 ] -> getPickupAt ( ) -> format ( JsonToJob :: $ STUART_DATE_FORMAT ) ; } if ( count ( $ job -> getDropoffs ( ) ) === 1 && $ job -> getDropoffs ( ) [ 0 ] -> getDropoffAt ( ) !== null ) { $ result [ 'job' ] [ 'dropoff_at' ] = $ job -> getDropoffs ( ) [ 0 ] -> getDropoffAt ( ) -> format ( JsonToJob :: $ STUART_DATE_FORMAT ) ; } $ pickups = array ( ) ; foreach ( $ job -> getPickups ( ) as $ pickup ) { $ pickups [ ] = JobToJson :: locationAsArray ( $ pickup ) ; } $ dropOffs = array ( ) ; foreach ( $ job -> getDropOffs ( ) as $ dropOff ) { $ dropOffs [ ] = array_merge ( JobToJson :: locationAsArray ( $ dropOff ) , array ( 'package_type' => $ dropOff -> getPackageType ( ) , 'package_description' => $ dropOff -> getPackageDescription ( ) , 'client_reference' => $ dropOff -> getClientReference ( ) ) ) ; } $ result [ 'job' ] [ 'pickups' ] = $ pickups ; $ result [ 'job' ] [ 'dropoffs' ] = $ dropOffs ; return json_encode ( $ result ) ; }

Converts a Job into a Stuart Job as JSON.

@param Job $job
@return string

Converts a Job into a Stuart Job as JSON .


public static function convert($json)
    {
        $body = json_decode($json);
        $job = new Job();

        $job->setId($body->id);
        $job->setTransportType(isset($body->transport_type) ? $body->transport_type : null);
        $job->setAssignmentCode(isset($body->assignment_code) ? $body->assignment_code : null);
        $job->setStatus($body->status);
        $job->setDistance($body->distance);
        $job->setDuration($body->duration);

        foreach ($body->deliveries as $delivery) {
            $job
                ->link(
                    $job->addPickup(self::fullTextAddress($delivery->pickup->address))
                        ->setPickupAt(\DateTime::createFromFormat(self::$STUART_DATE_FORMAT, $body->pickup_at))
                        ->setComment($delivery->pickup->comment)
                        ->setContactCompany($delivery->pickup->contact->company_name)
                        ->setContactFirstName($delivery->pickup->contact->firstname)
                        ->setContactLastName($delivery->pickup->contact->lastname)
                        ->setContactPhone($delivery->pickup->contact->phone)
                        ->setContactEmail($delivery->pickup->contact->email),
                    $job->addDropOff(self::fullTextAddress($delivery->dropoff->address))
                        ->setDropoffAt(\DateTime::createFromFormat(self::$STUART_DATE_FORMAT, $body->dropoff_at))
                        ->setPackageType($delivery->package_type)
                        ->setPackageDescription($delivery->package_description)
                        ->setClientReference($delivery->client_reference)
                        ->setComment($delivery->dropoff->comment)
                        ->setContactCompany($delivery->dropoff->contact->company_name)
                        ->setContactFirstName($delivery->dropoff->contact->firstname)
                        ->setContactLastName($delivery->dropoff->contact->lastname)
                        ->setContactPhone($delivery->dropoff->contact->phone)
                        ->setContactEmail($delivery->dropoff->contact->email)
                )
                ->setId($delivery->id)
                ->setStatus($delivery->status)
                ->setTrackingUrl($delivery->tracking_url);
        }

        $pricing = new Pricing();
        if (isset($body->pricing)) {
            if (isset($body->pricing->price_tax_included)) {
                $pricing->setPriceTaxIncluded($body->pricing->price_tax_included);
            }
            if (isset($body->pricing->price_tax_excluded)) {
                $pricing->setPriceTaxExcluded($body->pricing->price_tax_excluded);
            }
        }

        $job->setPricing($pricing);

        return $job;
    }

public static function convert ( $ json ) { $ body = json_decode ( $ json ) ; $ job = new Job ( ) ; $ job -> setId ( $ body -> id ) ; $ job -> setTransportType ( isset ( $ body -> transport_type ) ? $ body -> transport_type : null ) ; $ job -> setAssignmentCode ( isset ( $ body -> assignment_code ) ? $ body -> assignment_code : null ) ; $ job -> setStatus ( $ body -> status ) ; $ job -> setDistance ( $ body -> distance ) ; $ job -> setDuration ( $ body -> duration ) ; foreach ( $ body -> deliveries as $ delivery ) { $ job -> link ( $ job -> addPickup ( self :: fullTextAddress ( $ delivery -> pickup -> address ) ) -> setPickupAt ( \ DateTime :: createFromFormat ( self :: $ STUART_DATE_FORMAT , $ body -> pickup_at ) ) -> setComment ( $ delivery -> pickup -> comment ) -> setContactCompany ( $ delivery -> pickup -> contact -> company_name ) -> setContactFirstName ( $ delivery -> pickup -> contact -> firstname ) -> setContactLastName ( $ delivery -> pickup -> contact -> lastname ) -> setContactPhone ( $ delivery -> pickup -> contact -> phone ) -> setContactEmail ( $ delivery -> pickup -> contact -> email ) , $ job -> addDropOff ( self :: fullTextAddress ( $ delivery -> dropoff -> address ) ) -> setDropoffAt ( \ DateTime :: createFromFormat ( self :: $ STUART_DATE_FORMAT , $ body -> dropoff_at ) ) -> setPackageType ( $ delivery -> package_type ) -> setPackageDescription ( $ delivery -> package_description ) -> setClientReference ( $ delivery -> client_reference ) -> setComment ( $ delivery -> dropoff -> comment ) -> setContactCompany ( $ delivery -> dropoff -> contact -> company_name ) -> setContactFirstName ( $ delivery -> dropoff -> contact -> firstname ) -> setContactLastName ( $ delivery -> dropoff -> contact -> lastname ) -> setContactPhone ( $ delivery -> dropoff -> contact -> phone ) -> setContactEmail ( $ delivery -> dropoff -> contact -> email ) ) -> setId ( $ delivery -> id ) -> setStatus ( $ delivery -> status ) -> setTrackingUrl ( $ delivery -> tracking_url ) ; } $ pricing = new Pricing ( ) ; if ( isset ( $ body -> pricing ) ) { if ( isset ( $ body -> pricing -> price_tax_included ) ) { $ pricing -> setPriceTaxIncluded ( $ body -> pricing -> price_tax_included ) ; } if ( isset ( $ body -> pricing -> price_tax_excluded ) ) { $ pricing -> setPriceTaxExcluded ( $ body -> pricing -> price_tax_excluded ) ; } } $ job -> setPricing ( $ pricing ) ; return $ job ; }

Converts a JSON formatted Stuart Job into a Job object.

@param String $json
@return Job

Converts a JSON formatted Stuart Job into a Job object .


protected function free(\Throwable $exception = null)
    {
        $this->poll->free();

        while (!$this->queue->isEmpty()) {
            /** @var \Icicle\Awaitable\Delayed $delayed */
            $delayed = $this->queue->shift();
            $delayed->reject($exception ?: new ClosedException('The server was unexpectedly closed.'));
        }
    }

Frees resources associated with the server and closes the server.

@param \Throwable $exception Reason for closing the server.

Frees resources associated with the server and closes the server .


protected function free(Throwable $exception = null)
    {
        $this->poll->free();

        if (null !== $this->await) {
            $this->await->free();
        }

        while (!$this->readQueue->isEmpty()) {
            /** @var \Icicle\Awaitable\Delayed $delayed */
            $delayed = $this->readQueue->shift();
            $delayed->resolve();
        }

        while (!$this->writeQueue->isEmpty()) {
            /** @var \Icicle\Awaitable\Delayed $delayed */
            list( , , , $delayed) = $this->writeQueue->shift();
            $delayed->reject(
                $exception = $exception ?: new ClosedException('The datagram was unexpectedly closed.')
            );
        }
    }

Frees resources associated with the datagram and closes the datagram.

@param \Throwable|null $exception Reason for closing the datagram.

Frees resources associated with the datagram and closes the datagram .


public static function create($title = null, $x_label = null, $y_label = null, $chartData = array ()) {
		self::$instances++;
		return new DashboardChart($title, $x_label, $y_label, $chartData);
	}

public static function create ( $ title = null , $ x_label = null , $ y_label = null , $ chartData = array ( ) ) { self :: $ instances ++ ; return new DashboardChart ( $ title , $ x_label , $ y_label , $ chartData ) ; }

Creates a new instance of a DashboardChart

@param string The title of the chart
@param string The label of the X axis
@param string The label for the Y axis
@param array The chart data, in x/y pairs
@return DashboardChart


public function handleItem(SS_HTTPRequest $r) {
		if($r->param('ID') == "new") {
			$item = Object::create($this->relationClass);
		}
		else {
			$item = DataList::create($this->relationClass)->byID((int) $r->param('ID'));
		}
		if($item) {
			$handler = DashboardHasManyRelationEditor_ItemRequest::create($this->controller->getDashboard(), $this->controller, $this, $item);
			return $handler->handleRequest($r, DataModel::inst());
		}
		return $this->httpError(404);
	}

Handles a request for a record in the table

@param SS_HTTPRequest
@return SS_HTTPResponse


public function sort(SS_HTTPRequest $r) {
		if($items = $r->getVar('item')) {
			foreach($items as $position => $id) {
				if($item = DataList::create($this->relationClass)->byID((int) $id)) {
					$item->SortOrder = $position;
					$item->write();
				}
			}
			return new SS_HTTPResponse("OK");
		}
	}

public function sort ( SS_HTTPRequest $ r ) { if ( $ items = $ r -> getVar ( 'item' ) ) { foreach ( $ items as $ position => $ id ) { if ( $ item = DataList :: create ( $ this -> relationClass ) -> byID ( ( int ) $ id ) ) { $ item -> SortOrder = $ position ; $ item -> write ( ) ; } } return new SS_HTTPResponse ( "OK" ) ; } }

A controller action that handles the reordering of the list

@param SS_HTTPRequest
@return SS_HTTPResponse


public function Link($action = null) {
		return Controller::join_links($this->editor->Link(),"item",$this->item->ID ? $this->item->ID : "new",$action);
	}

public function Link ( $ action = null ) { return Controller :: join_links ( $ this -> editor -> Link ( ) , "item" , $ this -> item -> ID ? $ this -> item -> ID : "new" , $ action ) ; }

A link to this item as managed by the editor belonging to a dashbaord panel

@return string


public function DetailForm() {
		$form = Form::create(
			$this,
			"DetailForm",
			Injector::inst()->get($this->editor->relationClass)->getConfiguration(),
			FieldList::create(
				FormAction::create('saveDetail',_t('Dashboard.SAVE','Save'))
					->setUseButtonTag(true)
					->addExtraClass('ss-ui-action-constructive small'),
				FormAction::create('cancel',_t('Dashboard.CANCEL','Cancel'))
					->setUseButtonTag(true)
					->addExtraClass('small')
			)
		);
		$form->setHTMLID("Form_DetailForm_".$this->panel->ID."_".$this->item->ID);
		$form->loadDataFrom($this->item);
		$form->addExtraClass('dashboard-has-many-editor-detail-form-form');
		return $form;
	}

Provides a form to edit or create an object managed by the editor

@return Form


public function saveDetail($data, $form) {
		$item = $this->item;
		if(!$item->exists()) {
			$item->DashboardPanelID = $this->panel->ID;
			$sort = DataList::create($item->class)->max("SortOrder");
			$item->SortOrder = $sort+1;
			$item->write();
		}
		$form->saveInto($item);
		$item->write();
		return new SS_HTTPResponse("OK");
	}

public function saveDetail ( $ data , $ form ) { $ item = $ this -> item ; if ( ! $ item -> exists ( ) ) { $ item -> DashboardPanelID = $ this -> panel -> ID ; $ sort = DataList :: create ( $ item -> class ) -> max ( "SortOrder" ) ; $ item -> SortOrder = $ sort + 1 ; $ item -> write ( ) ; } $ form -> saveInto ( $ item ) ; $ item -> write ( ) ; return new SS_HTTPResponse ( "OK" ) ; }

Saves the DetailForm and writes or creates a new object managed by the editor

@param array The raw POST data from the form
@param Form The DetailForm object


public function RSSItems() {
		if(!$this->FeedURL) return false;
		$doc = new DOMDocument();
		@$doc->load($this->FeedURL);
		$items = $doc->getElementsByTagName('item');
		$feeds = array ();
		foreach ($items as $node) {
			$itemRSS = array (
				'title' => $node->getElementsByTagName('title')->item(0)->nodeValue,
				'desc' => $node->getElementsByTagName('description')->item(0)->nodeValue,
				'link' => $node->getElementsByTagName('link')->item(0)->nodeValue,
				'date' => $node->getElementsByTagName('pubDate')->item(0)->nodeValue
			);
			$feeds[] = $itemRSS;
		}
		$output = ArrayList::create(array());
		$count = 0;
		foreach($feeds as $item) {
			if($count >= $this->Count) break;
			// Cast the Date
			$date = new Date('Date');
			$date->setValue($item['date']);

			// Cast the Title
			$title = new Text('Title');
			$title->setValue($item['title']);

			$output->push(new ArrayData(array(
				'Title'			=> $title,
				'Date'			=> $date->Format($this->DateFormat),
				'Link'			=> $item['link']
			)));
			$count++;
		}

		return $output;

	}

public
function
RSSItems
(
)
{
if
(
!
$
this
->
FeedURL
)
return
false
;
$
doc
=
new
DOMDocument
(
)
;
@
$
doc
->
load
(
$
this
->
FeedURL
)
;
$
items
=
$
doc
->
getElementsByTagName
(
'item'
)
;
$
feeds
=
array
(
)
;
foreach
(
$
items
as
$
node
)
{
$
itemRSS
=
array
(
'title'
=>
$
node
->
getElementsByTagName
(
'title'
)
->
item
(
0
)
->
nodeValue
,
'desc'
=>
$
node
->
getElementsByTagName
(
'description'
)
->
item
(
0
)
->
nodeValue
,
'link'
=>
$
node
->
getElementsByTagName
(
'link'
)
->
item
(
0
)
->
nodeValue
,
'date'
=>
$
node
->
getElementsByTagName
(
'pubDate'
)
->
item
(
0
)
->
nodeValue
)
;
$
feeds
[
]
=
$
itemRSS
;
}
$
output
=
ArrayList
::
create
(
array
(
)
)
;
$
count
=
0
;
foreach
(
$
feeds
as
$
item
)
{
if
(
$
count
>=
$
this
->
Count
)
break
;
// Cast the Date
$
date
=
new
Date
(
'Date'
)
;
$
date
->
setValue
(
$
item
[
'date'
]
)
;
// Cast the Title
$
title
=
new
Text
(
'Title'
)
;
$
title
->
setValue
(
$
item
[
'title'
]
)
;
$
output
->
push
(
new
ArrayData
(
array
(
'Title'
=>
$
title
,
'Date'
=>
$
date
->
Format
(
$
this
->
DateFormat
)
,
'Link'
=>
$
item
[
'link'
]
)
)
)
;
$
count
++
;
}
return
$
output
;
}

Gets a list of all the items in the RSS feed given a user-provided URL, limit, and date format

@return ArrayList

Gets a list of all the items in the RSS feed given a user - provided URL limit and date format


public function RecentEdits() {
		$records = SiteTree::get()->sort("LastEdited DESC")->limit($this->Count);
		$set = ArrayList::create(array());
		foreach($records as $r) {
			$set->push(ArrayData::create(array(
				'EditLink' => Injector::inst()->get("CMSPagesController")->Link("edit/show/{$r->ID}"),
				'Title' => $r->Title
			)));
		}
		return $set;
	}

public
function
RecentEdits
(
)
{
$
records
=
SiteTree
::
get
(
)
->
sort
(
"LastEdited DESC"
)
->
limit
(
$
this
->
Count
)
;
$
set
=
ArrayList
::
create
(
array
(
)
)
;
foreach
(
$
records
as
$
r
)
{
$
set
->
push
(
ArrayData
::
create
(
array
(
'EditLink'
=>
Injector
::
inst
(
)
->
get
(
"CMSPagesController"
)
->
Link
(
"edit/show/{$r->ID}"
)
,
'Title'
=>
$
r
->
Title
)
)
)
;
}
return
$
set
;
}

Gets the recent edited pages, limited to a user provided number of records

@return ArrayList

Gets the recent edited pages limited to a user provided number of records


public function onAfterWrite() {
		if(!$this->owner->HasConfiguredDashboard && !$this->owner->DashboardPanels()->exists()) {
			foreach(SiteConfig::current_site_config()->DashboardPanels() as $p) {
				$clone = $p->duplicate();
				$clone->SiteConfigID = 0;
				$clone->MemberID = $this->owner->ID;
				$clone->write();
			}

			DB::query("UPDATE \"Member\" SET \"HasConfiguredDashboard\" = 1 WHERE \"ID\" = {$this->owner->ID}");
			$this->owner->flushCache();
		}
	}

Ensures that new members get the default dashboard configuration. Once it has been applied,
make sure this doesn't happen again, if for some reason a user insists on having an empty
dashboard.

Ensures that new members get the default dashboard configuration . Once it has been applied make sure this doesn t happen again if for some reason a user insists on having an empty dashboard .


protected function getTemplate() {
		$templateName = get_class($this) . '_' . $this->SubjectPage()->ClassName . '_' . $this->GridFieldName;
		if(SS_TemplateLoader::instance()->findTemplates($templateName)) {
			return $templateName;
		}
		return parent::getTemplate();
	}

protected function getTemplate ( ) { $ templateName = get_class ( $ this ) . '_' . $ this -> SubjectPage ( ) -> ClassName . '_' . $ this -> GridFieldName ; if ( SS_TemplateLoader :: instance ( ) -> findTemplates ( $ templateName ) ) { return $ templateName ; } return parent :: getTemplate ( ) ; }

Override to check if there is a custom template for this panel, otherwise fall back.

@return string

Override to check if there is a custom template for this panel otherwise fall back .


public function ViewAllLink() {
		if($grid = $this->getGrid()) {
			return Controller::join_links(
				Injector::inst()->get("CMSMain")->Link("edit"),
				"show",
				$this->SubjectPageID
			)."#Root_".$this->getTabForGrid();
		}
	}

public function ViewAllLink ( ) { if ( $ grid = $ this -> getGrid ( ) ) { return Controller :: join_links ( Injector :: inst ( ) -> get ( "CMSMain" ) -> Link ( "edit" ) , "show" , $ this -> SubjectPageID ) . "#Root_" . $ this -> getTabForGrid ( ) ; } }

Gets the link to view all records in a GridField

@return string


public function CreateModelLink() {
		if($grid = $this->getGrid()) {
			return Controller::join_links(
				Injector::inst()->get("CMSMain")->Link("edit"),
				"EditForm",
				"field",
				$this->GridFieldName,
				"item",
				"new",
				"?ID={$this->SubjectPageID}"
			);
		}
	}

public function CreateModelLink ( ) { if ( $ grid = $ this -> getGrid ( ) ) { return Controller :: join_links ( Injector :: inst ( ) -> get ( "CMSMain" ) -> Link ( "edit" ) , "EditForm" , "field" , $ this -> GridFieldName , "item" , "new" , "?ID={$this->SubjectPageID}" ) ; } }

Gets a link to create a new record in a GridField

@return string


public function getGridFieldsFor(SiteTree $page) {
		$grids = array ();
		if(!$page || !$page->exists()) return $grids;

		foreach($page->getCMSFields()->dataFields() as $field) {
			if($field instanceof GridField) {
				$grids[$field->getName()] = $field->Title();
			}
		}
		if(empty($grids)) {
			return array(
				'' => _t('Dashboard.NOGRIDFIELDS','There are no GridFields defined for that page.')
			);
		}
		return $grids;
	}

Gets the GridFields for a given page

@param SiteTree A given page
@return array


protected function getGrid() {
		if($this->SubjectPage()->exists() && $this->GridFieldName) {
			if($grid = $this->SubjectPage()->getCMSFields()->dataFieldByName($this->GridFieldName)) {
				$grid->setForm($this->Form());
				return $grid;
			}
		}
	}

protected function getGrid ( ) { if ( $ this -> SubjectPage ( ) -> exists ( ) && $ this -> GridFieldName ) { if ( $ grid = $ this -> SubjectPage ( ) -> getCMSFields ( ) -> dataFieldByName ( $ this -> GridFieldName ) ) { $ grid -> setForm ( $ this -> Form ( ) ) ; return $ grid ; } } }

Gets the grid field instance given the selected page and GridField name

@return GridField


protected function getTabForGrid() {
		if(!$this->SubjectPage()->exists() || !$this->GridFieldName) return false;
		$fields = $this->SubjectPage()->getCMSFields();
		if($fields->hasTabSet()) {
			foreach($fields->fieldByName("Root")->Tabs() as $tab) {
				if($tab->fieldByName($this->GridFieldName)) {
					return $tab->getName();
				}
			}
		}
		return false;
	}

protected function getTabForGrid ( ) { if ( ! $ this -> SubjectPage ( ) -> exists ( ) || ! $ this -> GridFieldName ) return false ; $ fields = $ this -> SubjectPage ( ) -> getCMSFields ( ) ; if ( $ fields -> hasTabSet ( ) ) { foreach ( $ fields -> fieldByName ( "Root" ) -> Tabs ( ) as $ tab ) { if ( $ tab -> fieldByName ( $ this -> GridFieldName ) ) { return $ tab -> getName ( ) ; } } } return false ; }

Gets the name of the tab for the selected grid field name. Allows direct linking
to the edit form to expose the grid.

@return string

Gets the name of the tab for the selected grid field name . Allows direct linking to the edit form to expose the grid .


public function GridFieldItems() {
		if($grid = $this->getGrid()) {
			$list = $grid->getList()
				->limit($this->Count)
				->sort("LastEdited DESC");
			$ret = ArrayList::create(array());
			foreach($list as $record) {
				$record->EditLink = Controller::join_links(
					Injector::inst()->get("CMSMain")->Link("edit"),
					"EditForm",
					"field",
					$this->GridFieldName,
					"item",
					$record->ID,
					"edit",
					"?ID={$this->SubjectPageID}"
				);
				$ret->push($record);
			}
			return $ret;
		}
	}

public
function
GridFieldItems
(
)
{
if
(
$
grid
=
$
this
->
getGrid
(
)
)
{
$
list
=
$
grid
->
getList
(
)
->
limit
(
$
this
->
Count
)
->
sort
(
"LastEdited DESC"
)
;
$
ret
=
ArrayList
::
create
(
array
(
)
)
;
foreach
(
$
list
as
$
record
)
{
$
record
->
EditLink
=
Controller
::
join_links
(
Injector
::
inst
(
)
->
get
(
"CMSMain"
)
->
Link
(
"edit"
)
,
"EditForm"
,
"field"
,
$
this
->
GridFieldName
,
"item"
,
$
record
->
ID
,
"edit"
,
"?ID={$this->SubjectPageID}"
)
;
$
ret
->
push
(
$
record
)
;
}
return
$
ret
;
}
}

Gets the records in this GridField summary. Provides edit links and a title label

@return ArrayList

Gets the records in this GridField summary . Provides edit links and a title label


public function gridsforpage(SS_HTTPRequest $r) {
		$pageid = (int) $r->requestVar('pageid');
		return Convert::array2json($this->panel->getGridFieldsFor(SiteTree::get()->byID($pageid)));
	}

public function gridsforpage ( SS_HTTPRequest $ r ) { $ pageid = ( int ) $ r -> requestVar ( 'pageid' ) ; return Convert :: array2json ( $ this -> panel -> getGridFieldsFor ( SiteTree :: get ( ) -> byID ( $ pageid ) ) ) ; }

Given a requested page, get the GridField names and provide a JSON response

@param SS_HTTPRequest The request object
@return string

Given a requested page get the GridField names and provide a JSON response


public function requestAccountData($start_index=1, $max_results=1000) {
    $get_variables = array(
      'start-index' => $start_index,
      'max-results' => $max_results,
      );
    $url = new gapiRequest(gapi::account_data_url);
    $response = $url->get($get_variables, $this->auth_method->generateAuthHeader());

    if (substr($response['code'], 0, 1) == '2') {
      return $this->accountObjectMapper($response['body']);
    } else {
      throw new Exception('GAPI: Failed to request account data. Error: "' . strip_tags($response['body']) . '"');
    }
  }

Request account data from Google Analytics

@param Int $start_index OPTIONAL: Start index of results
@param Int $max_results OPTIONAL: Max results returned


private function cleanErrorResponse($error) {
    if (strpos($error, '<html') !== false) {
      $error = preg_replace('/<(style|title|script)[^>]*>[^<]*<\/(style|title|script)>/i', '', $error);
      return trim(preg_replace('/\s+/', ' ', strip_tags($error)));
    }
    else
    {
      $json = json_decode($error);
      return isset($json->error->message) ? strval($json->error->message) : $error;
    }
  }

Clean error message from Google API

@param String $error Error message HTML or JSON from Google API


protected function processFilter($filter) {
    $valid_operators = '(!~|=~|==|!=|>|<|>=|<=|=@|!@)';

    $filter = preg_replace('/\s\s+/', ' ', trim($filter)); //Clean duplicate whitespace
    $filter = str_replace(array(',', ';'), array('\,', '\;'), $filter); //Escape Google Analytics reserved characters
    $filter = preg_replace('/(&&\s*|\|\|\s*|^)([a-z0-9]+)(\s*' . $valid_operators . ')/i','$1ga:$2$3',$filter); //Prefix ga: to metrics and dimensions
    $filter = preg_replace('/[\'\"]/i', '', $filter); //Clear invalid quote characters
    $filter = preg_replace(array('/\s*&&\s*/','/\s*\|\|\s*/','/\s*' . $valid_operators . '\s*/'), array(';', ',', '$1'), $filter); //Clean up operators

    if (strlen($filter) > 0) {
      return urlencode($filter);
    }
    else {
      return false;
    }
  }

Process filter string, clean parameters and convert to Google Analytics
compatible format

@param String $filter
@return String Compatible filter string

Process filter string clean parameters and convert to Google Analytics compatible format


protected function accountObjectMapper($json_string) {
    $json = json_decode($json_string, true);
    $results = array();

    foreach ($json['items'] as $item) {
      foreach ($item['webProperties'] as $property) {
        if (isset($property['profiles'][0]['id'])) {
          $property['ProfileId'] = $property['profiles'][0]['id'];
        }
        $results[] = new gapiAccountEntry($property);
      }
    }

    $this->account_entries = $results;

    return $results;
  }

protected function accountObjectMapper ( $ json_string ) { $ json = json_decode ( $ json_string , true ) ; $ results = array ( ) ; foreach ( $ json [ 'items' ] as $ item ) { foreach ( $ item [ 'webProperties' ] as $ property ) { if ( isset ( $ property [ 'profiles' ] [ 0 ] [ 'id' ] ) ) { $ property [ 'ProfileId' ] = $ property [ 'profiles' ] [ 0 ] [ 'id' ] ; } $ results [ ] = new gapiAccountEntry ( $ property ) ; } } $ this -> account_entries = $ results ; return $ results ; }

Report Account Mapper to convert the JSON to array of useful PHP objects

@param String $json_string
@return Array of gapiAccountEntry objects


protected function reportObjectMapper($json_string) {
    $json = json_decode($json_string, true);

    $this->results = null;
    $results = array();

    $report_aggregate_metrics = array();

    //Load root parameters

    // Start with elements from the root level of the JSON that aren't themselves arrays.
    $report_root_parameters = array_filter($json, function($var){
      return !is_array($var);
    });

    // Get the items from the 'query' object, and rename them slightly.
    foreach($json['query'] as $index => $value) {
      $new_index = lcfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $index))));
      $report_root_parameters[$new_index] = $value;
    }

    // Now merge in the profileInfo, as this is also mostly useful.
    array_merge($report_root_parameters, $json['profileInfo']);

    //Load result aggregate metrics

    foreach($json['totalsForAllResults'] as $index => $metric_value) {
      //Check for float, or value with scientific notation
      if (preg_match('/^(\d+\.\d+)|(\d+E\d+)|(\d+.\d+E\d+)$/', $metric_value)) {
        $report_aggregate_metrics[str_replace('ga:', '', $index)] = floatval($metric_value);
      } else {
        $report_aggregate_metrics[str_replace('ga:', '', $index)] = intval($metric_value);
      }
    }

    //Load result entries
    if(isset($json['rows'])){
      foreach($json['rows'] as $row) {
        $metrics = array();
        $dimensions = array();
        foreach($json['columnHeaders'] as $index => $header) {
          switch($header['columnType']) {
            case 'METRIC':
              $metric_value = $row[$index];

              //Check for float, or value with scientific notation
              if(preg_match('/^(\d+\.\d+)|(\d+E\d+)|(\d+.\d+E\d+)$/',$metric_value)) {
                $metrics[str_replace('ga:', '', $header['name'])] = floatval($metric_value);
              } else {
                $metrics[str_replace('ga:', '', $header['name'])] = intval($metric_value);
              }
              break;
            case 'DIMENSION':
              $dimensions[str_replace('ga:', '', $header['name'])] = strval($row[$index]);
              break;
            default:
              throw new Exception("GAPI: Unrecognized columnType '{$header['columnType']}' for columnHeader '{$header['name']}'");
          }
        }
        $results[] = new gapiReportEntry($metrics, $dimensions);
      }
    }

    $this->report_root_parameters = $report_root_parameters;
    $this->report_aggregate_metrics = $report_aggregate_metrics;
    $this->results = $results;

    return $results;
  }

Report Object Mapper to convert the JSON to array of useful PHP objects

@param String $json_string
@return Array of gapiReportEntry objects


public static function ArrayKeyExists($key, $search) {
    if (array_key_exists($key, $search)) {
      return $key;
    }
    if (!(is_string($key) && is_array($search))) {
      return false;
    }
    $key = strtolower($key);
    foreach ($search as $k => $v) {
      if (strtolower($k) == $key) {
        return $k;
      }
    }
    return false;
  }

public static function ArrayKeyExists ( $ key , $ search ) { if ( array_key_exists ( $ key , $ search ) ) { return $ key ; } if ( ! ( is_string ( $ key ) && is_array ( $ search ) ) ) { return false ; } $ key = strtolower ( $ key ) ; foreach ( $ search as $ k => $ v ) { if ( strtolower ( $ k ) == $ key ) { return $ k ; } } return false ; }

Case insensitive array_key_exists function, also returns
matching key.

@param String $key
@param Array $search
@return String Matching array key

Case insensitive array_key_exists function also returns matching key .


public function fetchToken($client_email, $key_file, $delegate_email = null) {
    $header = array(
      "alg" => self::header_alg,
      "typ" => self::header_typ,
    );

    $claimset = array(
      "iss" => $client_email,
      "scope" => self::scope_url,
      "aud" => self::request_url,
      "exp" => time() + (60 * 60),
      "iat" => time(),
    );

    if(!empty($delegate_email)) {
      $claimset["sub"] = $delegate_email;
    }

    $data = $this->base64URLEncode(json_encode($header)) . '.' . $this->base64URLEncode(json_encode($claimset));

    if (!file_exists($key_file)) {
      if ( !file_exists(__DIR__ . DIRECTORY_SEPARATOR . $key_file) ) {
        throw new Exception('GAPI: Failed load key file "' . $key_file . '". File could not be found.');
      } else {
        $key_file = __DIR__ . DIRECTORY_SEPARATOR . $key_file;
      }
    }

    $key_data = file_get_contents($key_file);

    if (empty($key_data)) {
      throw new Exception('GAPI: Failed load key file "' . $key_file . '". File could not be opened or is empty.');
    }

    openssl_pkcs12_read($key_data, $certs, 'notasecret');

    if (!isset($certs['pkey'])) {
      throw new Exception('GAPI: Failed load key file "' . $key_file . '". Unable to load pkcs12 check if correct p12 format.');
    }

    openssl_sign($data, $signature, openssl_pkey_get_private($certs['pkey']), "sha256");

    $post_variables = array(
      'grant_type' => self::grant_type,
      'assertion' => $data . '.' . $this->base64URLEncode($signature),
    );

    $url = new gapiRequest(self::request_url);
    $response = $url->post(null, $post_variables);
    $auth_token = json_decode($response['body'], true);

    if (substr($response['code'], 0, 1) != '2' || !is_array($auth_token) || empty($auth_token['access_token'])) {
      throw new Exception('GAPI: Failed to authenticate user. Error: "' . strip_tags($response['body']) . '"');
    }

    $this->auth_token = $auth_token['access_token'];

    return $this->auth_token;
  }

Authenticate Google Account with OAuth2

@param String $client_email
@param String $key_file
@param String $delegate_email
@return String Authentication token


public function getUrl($get_variables=null) {
    if (is_array($get_variables)) {
      $get_variables = '?' . str_replace('&', '&', urldecode(http_build_query($get_variables, '', '&')));
    } else {
      $get_variables = null;
    }

    return $this->url . $get_variables;
  }

public function getUrl ( $ get_variables = null ) { if ( is_array ( $ get_variables ) ) { $ get_variables = '?' . str_replace ( '&' , '&' , urldecode ( http_build_query ( $ get_variables , '' , '&' ) ) ) ; } else { $ get_variables = null ; } return $ this -> url . $ get_variables ; }

Return the URL to be requested, optionally adding GET variables

@param Array $get_variables
@return String

Return the URL to be requested optionally adding GET variables


public function post($get_variables=null, $post_variables=null, $headers=null) {
    return $this->request($get_variables, $post_variables, $headers);
  }

public function post ( $ get_variables = null , $ post_variables = null , $ headers = null ) { return $ this -> request ( $ get_variables , $ post_variables , $ headers ) ; }

Perform http POST request

@param Array $get_variables
@param Array $post_variables
@param Array $headers


public function get($get_variables=null, $headers=null) {
    return $this->request($get_variables, null, $headers);
  }

public function get ( $ get_variables = null , $ headers = null ) { return $ this -> request ( $ get_variables , null , $ headers ) ; }

Perform http GET request

@param Array $get_variables
@param Array $headers


public function request($get_variables=null, $post_variables=null, $headers=null) {
    $interface = self::http_interface;

    if (self::http_interface == 'auto')
      $interface = function_exists('curl_exec') ? 'curl' : 'fopen';

    switch ($interface) {
      case 'curl':
        return $this->curlRequest($get_variables, $post_variables, $headers);
      case 'fopen':
        return $this->fopenRequest($get_variables, $post_variables, $headers);
      default:
        throw new Exception('Invalid http interface defined. No such interface "' . self::http_interface . '"');
    }
  }

Perform http request

@param Array $get_variables
@param Array $post_variables
@param Array $headers


private function curlRequest($get_variables=null, $post_variables=null, $headers=null) {
    $ch = curl_init();

    if (is_array($get_variables)) {
      $get_variables = '?' . str_replace('&', '&', urldecode(http_build_query($get_variables, '', '&')));
    } else {
      $get_variables = null;
    }

    curl_setopt($ch, CURLOPT_URL, $this->url . $get_variables);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //CURL doesn't like google's cert

    if (is_array($post_variables)) {
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_variables, '', '&'));
    }

    if (is_array($headers)) {
      $string_headers = array();
      foreach ($headers as $key => $value) {
        $string_headers[] = "$key: $value";
      }
      curl_setopt($ch, CURLOPT_HTTPHEADER, $string_headers);
    }

    $response = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    curl_close($ch);

    return array('body' => $response, 'code' => $code);
  }

private
function
curlRequest
(
$
get_variables
=
,
$
post_variables
=
,
$
headers
=
)
{
$
ch
=
curl_init
(
)
;
if
(
is_array
(
$
get_variables
)
)
{
$
get_variables
=
'?'
.
str_replace
(
'&'
,
'&'
,
urldecode
(
http_build_query
(
$
get_variables
,
''
,
'&'
)
)
)
;
}
else
{
$
get_variables
=
;
}
curl_setopt
(
$
ch
,
CURLOPT_URL
,
$
this
->
url
.
$
get_variables
)
;
curl_setopt
(
$
ch
,
CURLOPT_RETURNTRANSFER
,
true
)
;
curl_setopt
(
$
ch
,
CURLOPT_SSL_VERIFYPEER
,
false
)
;
//CURL doesn't like google's cert
if
(
is_array
(
$
post_variables
)
)
{
curl_setopt
(
$
ch
,
CURLOPT_POST
,
true
)
;
curl_setopt
(
$
ch
,
CURLOPT_POSTFIELDS
,
http_build_query
(
$
post_variables
,
''
,
'&'
)
)
;
}
if
(
is_array
(
$
headers
)
)
{
$
string_headers
=
array
(
)
;
foreach
(
$
headers
as
$
key
=>
$
value
)
{
$
string_headers
[
]
=
"$key: $value"
;
}
curl_setopt
(
$
ch
,
CURLOPT_HTTPHEADER
,
$
string_headers
)
;
}
$
response
=
curl_exec
(
$
ch
)
;
$
code
=
curl_getinfo
(
$
ch
,
CURLINFO_HTTP_CODE
)
;
curl_close
(
$
ch
)
;
return
array
(
'body'
=>
$
response
,
'code'
=>
$
code
)
;
}

HTTP request using PHP CURL functions
Requires curl library installed and configured for PHP

@param Array $get_variables
@param Array $post_variables
@param Array $headers


private function fopenRequest($get_variables=null, $post_variables=null, $headers=null) {
    $http_options = array('method'=>'GET', 'timeout'=>3);

    $string_headers = '';
    if (is_array($headers)) {
      foreach ($headers as $key => $value) {
        $string_headers .= "$key: $value\r\n";
      }
    }

    if (is_array($get_variables)) {
      $get_variables = '?' . str_replace('&', '&', urldecode(http_build_query($get_variables, '', '&')));
    }
    else {
      $get_variables = null;
    }

    if (is_array($post_variables)) {
      $post_variables = str_replace('&', '&', urldecode(http_build_query($post_variables, '', '&')));
      $http_options['method'] = 'POST';
      $string_headers = "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($post_variables) . "\r\n" . $string_headers;
      $http_options['header'] = $string_headers;
      $http_options['content'] = $post_variables;
    }
    else {
      $post_variables = '';
      $http_options['header'] = $string_headers;
    }

    $context = stream_context_create(array('http'=>$http_options));
    $response = @file_get_contents($this->url . $get_variables, null, $context);

    return array('body'=>$response!==false?$response:'Request failed, consider using php5-curl module for more information.', 'code'=>$response!==false?'200':'400');
  }

HTTP request using native PHP fopen function
Requires PHP openSSL

@param Array $get_variables
@param Array $post_variables
@param Array $headers


public function RecentFiles() {
		$records = File::get()
			->filter(array(
				'ClassName:not' => 'Folder'
			))
			->sort("LastEdited DESC")
			->limit($this->Count);
		$set = ArrayList::create(array());
		foreach($records as $r) {
			$set->push(ArrayData::create(array(
				'EditLink' => Injector::inst()->get("AssetAdmin")->Link("EditForm/field/File/item/{$r->ID}/edit"),
				'Title' => $r->Title
			)));
		}
		return $set;
	}

Gets a list of the recently uploaded files to the CMS

@return ArrayList


public function duplicate($dowrite = true) {
		$clone = parent::duplicate(true);
		foreach($this->has_many() as $relationName => $relationClass) {
			foreach($this->$relationName() as $relObject) {
				$relClone = $relObject->duplicate(false);
				$relClone->DashboardPanelID = $clone->ID;
				$relClone->write();
			}
		}
		return $clone;
	}

public function duplicate ( $ dowrite = true ) { $ clone = parent :: duplicate ( true ) ; foreach ( $ this -> has_many ( ) as $ relationName => $ relationClass ) { foreach ( $ this -> $ relationName ( ) as $ relObject ) { $ relClone = $ relObject -> duplicate ( false ) ; $ relClone -> DashboardPanelID = $ clone -> ID ; $ relClone -> write ( ) ; } } return $ clone ; }

Duplicates this panel. Drills down into the has_many relations

@return DashboardPanel

Duplicates this panel . Drills down into the has_many relations


protected function getTemplate() {
		$templateName = get_class($this) . '_' . $this->ModelAdminClass . '_' . $this->ModelAdminModel;
		if(SS_TemplateLoader::instance()->findTemplates($templateName)) {
			return $templateName;
		}
		return parent::getTemplate();
	}

protected function getTemplate ( ) { $ templateName = get_class ( $ this ) . '_' . $ this -> ModelAdminClass . '_' . $ this -> ModelAdminModel ; if ( SS_TemplateLoader :: instance ( ) -> findTemplates ( $ templateName ) ) { return $ templateName ; } return parent :: getTemplate ( ) ; }

Override to check if there is a custom template for this panel, otherwise fall back

@return string

Override to check if there is a custom template for this panel otherwise fall back


public function ViewAllLink() {
		if($this->ModelAdminClass && $this->ModelAdminModel) {
			$url_segment = Injector::inst()->get($this->ModelAdminClass)->Link();
			return Controller::join_links($url_segment, $this->ModelAdminModel);
		}
	}

public function ViewAllLink ( ) { if ( $ this -> ModelAdminClass && $ this -> ModelAdminModel ) { $ url_segment = Injector :: inst ( ) -> get ( $ this -> ModelAdminClass ) -> Link ( ) ; return Controller :: join_links ( $ url_segment , $ this -> ModelAdminModel ) ; } }

Gets the link to view all records in ModelAdmin

@return string


public function ModelAdminItems() {
		if($this->ModelAdminModel) {
			$SNG= Injector::inst()->get($this->ModelAdminModel);
			if($SNG->hasExtension("Versioned")) {
				Versioned::reading_stage("Stage");
			}
			$records = DataList::create($this->ModelAdminModel)
				->limit($this->Count)
				->sort("LastEdited DESC");
			$url_segment = Injector::inst()->get($this->ModelAdminClass)->Link();
			$ret = ArrayList::create(array());
			foreach($records as $rec) {
				$rec->EditLink = Controller::join_links(
					$url_segment,
					$this->ModelAdminModel,
					"EditForm",
					"field",
					$this->ModelAdminModel,
					"item",
					$rec->ID,
					"edit"
				);
				$ret->push($rec);
			}
			return $ret;
		}
	}

public
function
ModelAdminItems
(
)
{
if
(
$
this
->
ModelAdminModel
)
{
$
SNG
=
Injector
::
inst
(
)
->
get
(
$
this
->
ModelAdminModel
)
;
if
(
$
SNG
->
hasExtension
(
"Versioned"
)
)
{
Versioned
::
reading_stage
(
"Stage"
)
;
}
$
records
=
DataList
::
create
(
$
this
->
ModelAdminModel
)
->
limit
(
$
this
->
Count
)
->
sort
(
"LastEdited DESC"
)
;
$
url_segment
=
Injector
::
inst
(
)
->
get
(
$
this
->
ModelAdminClass
)
->
Link
(
)
;
$
ret
=
ArrayList
::
create
(
array
(
)
)
;
foreach
(
$
records
as
$
rec
)
{
$
rec
->
EditLink
=
Controller
::
join_links
(
$
url_segment
,
$
this
->
ModelAdminModel
,
"EditForm"
,
"field"
,
$
this
->
ModelAdminModel
,
"item"
,
$
rec
->
ID
,
"edit"
)
;
$
ret
->
push
(
$
rec
)
;
}
return
$
ret
;
}
}

Gets the records in this ModelAdmin summary. Provides edit links and a title label

@return ArrayList

Gets the records in this ModelAdmin summary . Provides edit links and a title label


public function modelsforpanel(SS_HTTPRequest $r) {
		$panel = $r->requestVar('modeladminpanel');
		return Convert::array2json($this->panel->getManagedModelsFor($panel));
	}

public function modelsforpanel ( SS_HTTPRequest $ r ) { $ panel = $ r -> requestVar ( 'modeladminpanel' ) ; return Convert :: array2json ( $ this -> panel -> getManagedModelsFor ( $ panel ) ) ; }

Given a requested ModelAdmin subclass, get the managed models and provide a JSON response

@param SS_HTTPRequest The request object
@return string

Given a requested ModelAdmin subclass get the managed models and provide a JSON response


public function providePermissions() {
		$title = _t("Dashboard.MENUTITLE", LeftAndMain::menu_title_for_class('Dashboard'));
		return array(
			"CMS_ACCESS_Dashboard" => array(
				'name' => _t('Dashboard.ACCESS', "Access to '{title}' section", array('title' => $title)),
				'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access'),
				'help' => _t(
					'Dashboard.ACCESS_HELP',
					'Allow use of the CMS Dashboard'
				)
			),
			"CMS_ACCESS_DashboardAddPanels" => array(
				'name' => _t('Dashboard.ADDPANELS', "Add dashboard panels"),
				'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access'),
				'help' => _t(
					'Dashboard.ACCESS_HELP',
					'Allow user to add panels to his/her dashboard'
				)
			),
			"CMS_ACCESS_DashboardConfigurePanels" => array(
				'name' => _t('Dashboard.CONFIGUREANELS', "Configure dashboard panels"),
				'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access'),
				'help' => _t(
					'Dashboard.ACCESS_HELP',
					'Allow user to configure his/her dashboard panels'
				),
			),
			"CMS_ACCESS_DashboardDeletePanels" => array(
				'name' => _t('Dashboard.DELETEPANELS', "Remove dashboard panels"),
				'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access'),
				'help' => _t(
					'Dashboard.ACCESS_HELP',
					'Allow user to remove panels from his/her dashboard'
				)
			)
		);
	}

Provides custom permissions to the Security section

@return array


public function sort(SS_HTTPRequest $r) {
		if($sort = $r->requestVar('dashboard-panel')) {
			foreach($sort as $index => $id) {
				if($panel = DashboardPanel::get()->byID((int) $id)) {
					if($panel->MemberID == Member::currentUserID()) {
						$panel->SortOrder = $index;
						$panel->write();
					}
				}
			}
		}
	}

public function sort ( SS_HTTPRequest $ r ) { if ( $ sort = $ r -> requestVar ( 'dashboard-panel' ) ) { foreach ( $ sort as $ index => $ id ) { if ( $ panel = DashboardPanel :: get ( ) -> byID ( ( int ) $ id ) ) { if ( $ panel -> MemberID == Member :: currentUserID ( ) ) { $ panel -> SortOrder = $ index ; $ panel -> write ( ) ; } } } } }

A controller action that handles the reordering of the panels

@param SS_HTTPRequest The current request
@return SS_HTTPResponse


public function setdefault(SS_HTTPRequest $r) {
		foreach(SiteConfig::current_site_config()->DashboardPanels() as $panel) {
			$panel->delete();
		}
		foreach(Member::currentUser()->DashboardPanels() as $panel) {
			$clone = $panel->duplicate();
			$clone->MemberID = 0;
			$clone->SiteConfigID = SiteConfig::current_site_config()->ID;
			$clone->write();
		}
		return new SS_HTTPResponse(_t('Dashboard.SETASDEFAULTSUCCESS','Success! This dashboard configuration has been set as the default for all new members.'));
	}

A controller action that handles setting the default dashboard configuration

@param SS_HTTPRequest The current request
@return SS_HTTPResponse


public function applytoall(SS_HTTPRequest $r) {
		$members = Permission::get_members_by_permission(array("CMS_ACCESS_Dashboard","ADMIN"));
		foreach($members as $member) {
			if($member->ID == Member::currentUserID()) continue;

			$member->DashboardPanels()->removeAll();
			foreach(Member::currentUser()->DashboardPanels() as $panel) {
				$clone = $panel->duplicate();
				$clone->MemberID = $member->ID;
				$clone->write();
			}
		}
		return new SS_HTTPResponse(_t('Dashboard.APPLYTOALLSUCCESS','Success! This dashboard configuration has been applied to all members who have dashboard access.'));
	}

A controller action that handles the application of a dashboard configuration to all members

@param SS_HTTPRequest The current request
@return SS_HTTPResponse


public function panel(SS_HTTPRequest $r) {
		if($this->panel->canView()) {
			return $this->panel->PanelHolder();
		}
		return $this->httpError(403);
	}

public function panel ( SS_HTTPRequest $ r ) { if ( $ this -> panel -> canView ( ) ) { return $ this -> panel -> PanelHolder ( ) ; } return $ this -> httpError ( 403 ) ; }

Renders the panel in this request

@param SS_HTTPRequest
@return SSViewer


public function delete(SS_HTTPRequest $r) {
		if($this->panel->canDelete()) {
			$this->panel->delete();
			return new SS_HTTPResponse("OK");
		}
	}

public function delete ( SS_HTTPRequest $ r ) { if ( $ this -> panel -> canDelete ( ) ) { $ this -> panel -> delete ( ) ; return new SS_HTTPResponse ( "OK" ) ; } }

Delets the panel in this request

@param SS_HTTPRequest
@return SS_HTTPResponse


public function ConfigureForm() {
		$form = Form::create(
			$this,
			"ConfigureForm",
			$this->panel->getConfiguration(),
			FieldList::create(
				FormAction::create("saveConfiguration",_t('Dashboard.SAVE','Save'))
					->setUseButtonTag(true)
					->addExtraClass('ss-ui-action-constructive'),
				FormAction::create("cancel",_t('Dashboard.CANCEL','Cancel'))
					->setUseButtonTag(true)
			)
		);
		$form->loadDataFrom($this->panel);
		$form->setHTMLID("Form_ConfigureForm_".$this->panel->ID);
		$form->addExtraClass("configure-form");
		return $form;
	}

public function ConfigureForm ( ) { $ form = Form :: create ( $ this , "ConfigureForm" , $ this -> panel -> getConfiguration ( ) , FieldList :: create ( FormAction :: create ( "saveConfiguration" , _t ( 'Dashboard.SAVE' , 'Save' ) ) -> setUseButtonTag ( true ) -> addExtraClass ( 'ss-ui-action-constructive' ) , FormAction :: create ( "cancel" , _t ( 'Dashboard.CANCEL' , 'Cancel' ) ) -> setUseButtonTag ( true ) ) ) ; $ form -> loadDataFrom ( $ this -> panel ) ; $ form -> setHTMLID ( "Form_ConfigureForm_" . $ this -> panel -> ID ) ; $ form -> addExtraClass ( "configure-form" ) ; return $ form ; }

Gets the configuration form for this panel and handles the form input

@return Form