private function request ( $method, $url, array $url_parameters = [], array $options = [] )
    {
        $method = mb_strtoupper($method);

        if (!empty($url_parameters)) {
          $options['query'] = $url_parameters;
        }

        // Set JSON headers
        $options['headers']['Accept']       = 'application/json';
        $options['headers']['Content-Type'] = 'application/json; charset=utf-8';

        // Set "on behalf of user" header
        if ( mb_strlen($this->on_behalf_of_user) ) {
            $options['headers']['X-On-Behalf-Of'] = $this->on_behalf_of_user;
        }

        $http_client_response = $this->http_client->request( $method, $url, $options );
        if ( !is_object($http_client_response) ) {
            throw new \RuntimeException('Unable to create HTTP client request.');
        }

        // Turn HTTP client's response into our own.
        $response = new Response(
            $http_client_response->getStatusCode(),
            $http_client_response->getReasonPhrase(),
            $http_client_response->getBody(),
            $http_client_response->getHeaders()
        );

        $this->setLastResponse($response);

        return $response;
    }

Executes a request.

@param String $method         GET, PUT, POST, DELETE
@param String $url            E. g. tickets/1
@param Array  $url_parameters E. g. [ 'expand' => true, ]

@return Response object


public function post( $url, array $data = [], array $url_parameters = [] )
    {
        $response = $this->request(
            'POST',
            $url,
            $url_parameters,
            [ 'json' => $data, ]
        );

        return $response;
    }

public function post ( $ url , array $ data = [ ] , array $ url_parameters = [ ] ) { $ response = $ this -> request ( 'POST' , $ url , $ url_parameters , [ 'json' => $ data , ] ) ; return $ response ; }

Executes POST request.

@param String $url            E. g. tickets/1
@param Array $data            Array with data to send as JSON.
@param Array  $url_parameters E. g. [ 'expand' => true, ]

@return Response object


public function put( $url, array $data = [], array $url_parameters = [] )
    {
        $response = $this->request(
            'PUT',
            $url,
            $url_parameters,
            [ 'json' => $data, ]
        );

        return $response;
    }

public function put ( $ url , array $ data = [ ] , array $ url_parameters = [ ] ) { $ response = $ this -> request ( 'PUT' , $ url , $ url_parameters , [ 'json' => $ data , ] ) ; return $ response ; }

Executes PUT request.

@param String $url            E. g. tickets/1
@param Array $data            Array with data to send as JSON.
@param Array  $url_parameters E. g. [ 'expand' => true, ]

@return Response object


public function getForTicket($ticket_id)
    {
        if ( !empty( $this->getValues() ) ) {
            throw new \RuntimeException('Object already contains values, getForTicket() not possible, use a new object');
        }

        $this->clearError();

        $ticket_id = intval($ticket_id);
        if ( empty($ticket_id) ) {
            throw new \RuntimeException('Missing ticket ID');
        }

        $url = $this->getURL(
            'get_for_ticket',
            [
                'ticket_id' => $ticket_id,
            ]
        );
        $response = $this->getClient()->get(
            $url,
            [
                'expand' => true,
            ]
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
            return $this;
        }

        // Return array of TicketArticle objects.
        $ticket_articles = [];
        foreach ( $response->getData() as $ticket_article_data ) {
            $ticket_article = $this->getClient()->resource( get_class($this) );
            $ticket_article->setRemoteData($ticket_article_data);
            $ticket_articles[] = $ticket_article;
        }

        return $ticket_articles;
    }

Fetches TicketArticle objects for given ticket ID.

@param integer $ticket_id      ID of ticket to fetch article data for.

@return array                Array of TicketArticle objects.

Fetches TicketArticle objects for given ticket ID .


public function getValue($key)
    {
        if ( array_key_exists( $key, $this->values ) ) {
            return $this->values[$key];
        }

        $remote_data = $this->getRemoteData();
        if ( array_key_exists( $key, $remote_data ) ) {
            return $remote_data[$key];
        }

        return null;
    }

public function getValue ( $ key ) { if ( array_key_exists ( $ key , $ this -> values ) ) { return $ this -> values [ $ key ] ; } $ remote_data = $ this -> getRemoteData ( ) ; if ( array_key_exists ( $ key , $ remote_data ) ) { return $ remote_data [ $ key ] ; } return null ; }

Gets value of object.

First, it's been checked if the key exists in the local values that will be saved later in Zammad
by a call to save().

If not found, additionally the remote data will be searched for the key. This
ensures that a value is being returned that hasn't been changed locally.

@param string $key       Key to fetch value for.

@return mixed            Value or null if not found. Null could also be the set value.


public function get($object_id)
    {
        if ( !empty( $this->getValues() ) ) {
            throw new AlreadyFetchedObjectException('Object already contains values, get() not possible, use a new object');
        }

        if ( empty($object_id) ) {
            throw new \RuntimeException('Missing object ID');
        }

        $url = $this->getURL(
            'get',
            [
                'object_id' => $object_id,
            ]
        );

        $response = $this->getClient()->get(
            $url,
            [
                'expand' => true,
            ]
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
        }
        else {
            $this->clearError();
            $this->setRemoteData( $response->getData() );
        }

        return $this;
    }

Fetches object data for given object ID.

@param mixed $object_id      ID of object to fetch, false value or omit to fetch all objects.

@return object               This object.

Fetches object data for given object ID .


public function all( $page = null, $objects_per_page = null )
    {
        if ( !empty( $this->getValues() ) ) {
            throw new AlreadyFetchedObjectException('Object already contains values, all() not possible, use a new object');
        }

        if ( isset($page) && $page <= 0 ) {
            throw new \RuntimeException('Parameter page must be > 0');
        }
        if ( isset($objects_per_page) && $objects_per_page <= 0 ) {
            throw new \RuntimeException('Parameter objects_per_page must be > 0');
        }
        if (
            ( isset($page) && !isset($objects_per_page) )
            || ( !isset($page) && isset($objects_per_page) )
        ) {
            throw new \RuntimeException('Parameters page and objects_per_page must both be given');
        }

        if ( !isset($page) || !isset($objects_per_page) ) {
            return $this->allWithoutPagination();
        }

        $url_parameters = [
            'expand' => true,
        ];

        if ( isset($page) && isset($objects_per_page) ) {
            $url_parameters['page']     = $page;
            $url_parameters['per_page'] = $objects_per_page;
        }

        $url      = $this->getURL('all');
        $response = $this->getClient()->get(
            $url,
            $url_parameters
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
            return $this;
        }

        $this->clearError();

        // Return array of resource objects if no $object_id was given.
        // Note: the resource object (this object) used to execute get() will be left empty in this case.
        $objects       = [];
        foreach ( $response->getData() as $object_data ) {
            $object = $this->getClient()->resource( get_class($this) );
            $object->setRemoteData($object_data);
            $objects[] = $object;
        }

        return $objects;
    }

Fetches object data for all objects of this type.
Pagination available.

@param integer $page                 Page of objects, optional, if given, $objects_per_page must also be given.
@param integer $objects_per_page     Number of objects per page, optional, if given, $page must also be given.

@return mixed                        Returns array of ZammadAPIClient\Resource\... objects
or this object on failure.

Fetches object data for all objects of this type . Pagination available .


protected function create()
    {
        if ( !empty( $this->getID() ) ) {
            throw new \Exception('Object already has an ID, create() not possible');
        }

        if ( !$this->isDirty() ) {
            return $this;
        }

        $url      = $this->getURL('create');
        $response = $this->getClient()->post(
            $url,
            $this->getUnsavedValues(),
            [
                'expand' => true,
            ]
         );
        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
            return $this;
        }

        $this->clearError();
        $this->setRemoteData( $response->getData() );
        $this->clearUnsavedValues();

        return $this;
    }

Creates a new object with the current data.

@return object      This object

Creates a new object with the current data .


protected function update()
    {
        $object_id = $this->getID();
        if ( empty($object_id) ) {
            throw new \Exception('Object has no ID, update() not possible');
        }

        if ( !$this->isDirty() ) {
            return $this;
        }

        $url = $this->getURL(
            'update',
            [
                'object_id' => $object_id,
            ]
        );

        $response = $this->getClient()->put(
            $url,
            $this->getUnsavedValues(),
            [
                'expand' => true,
            ]
        );
        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
            return $this;
        }

        $this->clearError();
        $this->setRemoteData( $response->getData() );
        $this->clearUnsavedValues();

        return $this;
    }

Updates an existing object with the current data.

@return object      This object

Updates an existing object with the current data .


public function delete()
    {
        // Delete object in Zammad.
        $object_id = $this->getID();
        if ( !empty($object_id) ) {
            $url = $this->getURL(
                'delete',
                [
                    'object_id' => $object_id,
                ]
            );

            $response = $this->getClient()->delete(
                $url,
                [
                    'expand' => true,
                ]
            );
            if ( $response->hasError() ) {
                $this->setError( $response->getError() );
                return $this;
            }
        }

        // Clear data of this (local) object.
        $this->clearError();
        $this->clearRemoteData();
        $this->clearUnsavedValues();

        return $this;
    }

public
function
delete
(
)
{
// Delete object in Zammad.
$
object_id
=
$
this
->
getID
(
)
;
if
(
!
empty
(
$
object_id
)
)
{
$
url
=
$
this
->
getURL
(
'delete'
,
[
'object_id'
=>
$
object_id
,
]
)
;
$
response
=
$
this
->
getClient
(
)
->
delete
(
$
url
,
[
'expand'
=>
true
,
]
)
;
if
(
$
response
->
hasError
(
)
)
{
$
this
->
setError
(
$
response
->
getError
(
)
)
;
return
$
this
;
}
}
// Clear data of this (local) object.
$
this
->
clearError
(
)
;
$
this
->
clearRemoteData
(
)
;
$
this
->
clearUnsavedValues
(
)
;
return
$
this
;
}

Deletes the data of this object.
If data contains an ID, the object will also be deleted in Zammad.

@return object      This object

Deletes the data of this object . If data contains an ID the object will also be deleted in Zammad .


protected function getURL( $method_name, array $placeholder_values = [] )
    {
        if ( !array_key_exists( $method_name, $this::URLS ) ) {
            throw new \RuntimeException(
                "Method '$method_name' is not supported for "
                . get_class($this)
                . ' resource'
            );
        }

        $url = $this::URLS[$method_name];
        foreach ( $placeholder_values as $placeholder => $value ) {
            $url = preg_replace( "/\{$placeholder\}/", "$value", $url );
        }

        return $url;
    }

Returns the URL for the given method name, including its replaced placeholders.

@param string $method_name               E. g. 'get', 'all', etc.
@param array  $placeholder_values        Array of placeholder => value pairs,
e. g. [ 'object_id' => 2 ] will replace
{object_id} in URL with 2.

@return string                           URL, e. g. 'tickets/10'.

Returns the URL for the given method name including its replaced placeholders .


public function get($object_id, $object_type = 'Ticket')
    {
        $this->clearError();

        $object_id = intval($object_id);
        if ( empty($object_id) ) {
            throw new \RuntimeException('Missing object ID');
        }

        $response = $this->getClient()->get(
            $this->getURL('get'),
            [
                'object' => $object_type,
                'o_id'   => $object_id,
            ]
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
        }
        else {
            $this->clearError();
            $this->setRemoteData( $response->getData() );
        }

        return $this;
    }

public
function
get
(
$
object_id
,
$
object_type
=
'Ticket'
)
{
$
this
->
clearError
(
)
;
$
object_id
=
intval
(
$
object_id
)
;
if
(
empty
(
$
object_id
)
)
{
throw
new
\
RuntimeException
(
'Missing object ID'
)
;
}
$
response
=
$
this
->
getClient
(
)
->
get
(
$
this
->
getURL
(
'get'
)
,
[
'object'
=>
$
object_type
,
'o_id'
=>
$
object_id
,
]
)
;
if
(
$
response
->
hasError
(
)
)
{
$
this
->
setError
(
$
response
->
getError
(
)
)
;
}
else
{
$
this
->
clearError
(
)
;
$
this
->
setRemoteData
(
$
response
->
getData
(
)
)
;
}
return
$
this
;
}

Fetches tags of an object.

@param integer $object_id    ID of the object to fetch tags for.
@param string $object_type   Type of object to fetch tags for (e. g. 'Ticket').

@return object               This object.


public function add($object_id, $tag, $object_type = 'Ticket')
    {
        $this->clearError();

        $object_id = intval($object_id);
        if ( empty($object_id) ) {
            throw new \RuntimeException('Missing object ID');
        }

        if ( empty($tag) ) {
            throw new \RuntimeException('Missing tag');
        }

        $response = $this->getClient()->get(
            $this->getURL('add'),
            [
                'object' => $object_type,
                'o_id'   => $object_id,
                'item'   => $tag,
            ]
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
        }

        return $this;
    }

public
function
add
(
$
object_id
,
$
tag
,
$
object_type
=
'Ticket'
)
{
$
this
->
clearError
(
)
;
$
object_id
=
intval
(
$
object_id
)
;
if
(
empty
(
$
object_id
)
)
{
throw
new
\
RuntimeException
(
'Missing object ID'
)
;
}
if
(
empty
(
$
tag
)
)
{
throw
new
\
RuntimeException
(
'Missing tag'
)
;
}
$
response
=
$
this
->
getClient
(
)
->
get
(
$
this
->
getURL
(
'add'
)
,
[
'object'
=>
$
object_type
,
'o_id'
=>
$
object_id
,
'item'
=>
$
tag
,
]
)
;
if
(
$
response
->
hasError
(
)
)
{
$
this
->
setError
(
$
response
->
getError
(
)
)
;
}
return
$
this
;
}

Adds a tag to an object.

@param integer $object_id    ID of the object to fetch tags for.
@param string $tag           Tag to add.
@param string $object_type   Type of object to fetch tags for (e. g. 'Ticket').

@return object               This object.


public function search($search_term, $page = null, $objects_per_page = null)
    {
        $this->clearError();

        if ( empty($search_term) ) {
            throw new \RuntimeException('Missing search term');
        }

        $response = $this->getClient()->get(
            $this->getURL('search'),
            [
                'term' => $search_term,
            ]
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
        }

        $this->clearError();

        // Return array of resource objects if no $object_id was given.
        // Note: the resource object (this object) used to execute get() will be left empty in this case.
        $objects = [];
        foreach ( $response->getData() as $object_data ) {
            $object = $this->getClient()->resource( get_class($this) );
            $object->setRemoteData($object_data);
            $objects[] = $object;
        }

        return $objects;
    }

Fetches tags for given search term.
Pagination available.

@param string  $search_term          Search term.
@param integer $page                 Page of tags, optional, if given, $objects_per_page must also be given
@param integer $objects_per_page     Number of tags per page, optional, if given, $page must also be given

@return mixed                        Returns array of ZammadAPIClient\Resource\... objects
or this object on failure.

Fetches tags for given search term . Pagination available .


public function remove($object_id, $tag, $object_type = 'Ticket')
    {
        $this->clearError();

        if ( empty($object_id) ) {
            throw new \RuntimeException('Missing object ID');
        }

        if ( empty($tag) ) {
            throw new \RuntimeException('Missing tag');
        }

        // Delete object in Zammad.
        $response = $this->getClient()->get(
            $this->getURL('remove'),
            [
                'object' => $object_type,
                'o_id'   => $object_id,
                'item'   => $tag,
            ]
        );

        if ( $response->hasError() ) {
            $this->setError( $response->getError() );
            return $this;
        }

        // Clear data of this (local) object.
        $this->clearError();
        $this->clearRemoteData();
        $this->clearUnsavedValues();

        return $this;
    }

public
function
remove
(
$
object_id
,
$
tag
,
$
object_type
=
'Ticket'
)
{
$
this
->
clearError
(
)
;
if
(
empty
(
$
object_id
)
)
{
throw
new
\
RuntimeException
(
'Missing object ID'
)
;
}
if
(
empty
(
$
tag
)
)
{
throw
new
\
RuntimeException
(
'Missing tag'
)
;
}
// Delete object in Zammad.
$
response
=
$
this
->
getClient
(
)
->
get
(
$
this
->
getURL
(
'remove'
)
,
[
'object'
=>
$
object_type
,
'o_id'
=>
$
object_id
,
'item'
=>
$
tag
,
]
)
;
if
(
$
response
->
hasError
(
)
)
{
$
this
->
setError
(
$
response
->
getError
(
)
)
;
return
$
this
;
}
// Clear data of this (local) object.
$
this
->
clearError
(
)
;
$
this
->
clearRemoteData
(
)
;
$
this
->
clearUnsavedValues
(
)
;
return
$
this
;
}

Removes a tag from an object.

@param integer $object_id    ID of the object to fetch tags for.
@param string $tag           Tag to remove.
@param string $object_type   Type of object to fetch tags for (e. g. 'Ticket').

@return object               This object.


protected function shmTeardown($file) {
    // verify the shmop extension is loaded
    if (!extension_loaded('shmop')) {
      throw new \Exception(__CLASS__ . ": Please make sure your PHP setup has the 'shmop' extension enabled.", self::EXCEPTION_NO_SHMOP);
    }

    // Get actual file path
    $rfile = realpath($file);

  // If the file cannot be found, except away
    if (false === $rfile) {
      throw new \Exception(__CLASS__ . ": Database file '{$file}' does not seem to exist.", self::EXCEPTION_DBFILE_NOT_FOUND);
    }

    $shmKey = self::getShmKey($rfile);

  // Try to open the memory segment for writing
    $shmId  = @shmop_open($shmKey, 'w', 0, 0);
    if (false === $shmId) {
      throw new \Exception(__CLASS__ . ": Unable to access shared memory block '{$shmKey}' for writing.", self::EXCEPTION_SHMOP_WRITING_FAILED);
    }

    // Delete and close the descriptor
    shmop_delete($shmId);
    shmop_close($shmId);
  }

Tear down a shared memory segment created for the given file

@access protected
@param string $file  Filename of the BIN database whise segment must be deleted
@throws \Exception


private function readProxyType($pointer) {
    if (false === $pointer) {
      // Deal with invalid IPs
      $proxyType = self::INVALID_IP_ADDRESS;
    } elseif (0 === self::$columns[self::PROXY_TYPE][$this->type]) {
      // If the field is not suported, return accordingly
      $proxyType = self::FIELD_NOT_SUPPORTED;
    } else {
      // Read proxy type
      $proxyType = $this->readString($pointer + self::$columns[self::PROXY_TYPE][$this->type]);
    }
    return $proxyType;
  }

High level function to fetch the proxy type

@access private
@param int $pointer  Position to read from, if false, return self::INVALID_IP_ADDRESS
@return string


public function getConnectionInfo($d)
    {
        return sprintf(self::URL_CONNECTION_INFO, $d->server, $d->key, $d->ts);
    }

public function getConnectionInfo ( $ d ) { return sprintf ( self :: URL_CONNECTION_INFO , $ d -> server , $ d -> key , $ d -> ts ) ; }

Return connection info for long polling.

@param $d

@return string

Return connection info for long polling .


public function doLoop()
    {
        $server = $this->getServerData();
        $initial = $this->getConnectionInfo($server);

        $user = new User($this->vk);

        $userMap = [];
        $userCache = [];

        /*
         * @param $id
         * @return Model\User
         */
        $fetchData = function ($id) use ($user, &$userMap, &$userCache) {
            if (!isset($userMap[$id])) {
                $userMap[$id] = count($userCache);
                $userCache[] = $user->get($id)->response->get();
            }

            return $userCache[$userMap[$id]];
        };

        while ($data = $this->guzzle->get($initial)->json(['object' => true])) {
            $server->ts = $data->ts;
            $initial = $this->getConnectionInfo($server);

            foreach ($data->updates as $update) {
                /*
                 * @var $user Model\User
                 */
                switch ($update[0]) {
                    case LP::MESSAGE_ADD:
                        $user = $fetchData($update[3]);
                        if ($update[2] & 2) {
                            continue;
                        }
                        printf("New message from %s '%s'\n", $user->getName(), $update[6]);
                        var_dump($update);
                        break;
                    case LP::MESSAGE_WRITE:
                        $user = $fetchData($update[1]);
                        printf("User %s writing\n", $user->getName());
                        break;
                    case LP::DATA_ADD:
                        break;
                    case LP::FRIEND_OFFLINE:
                        $user = $fetchData($update[1] * -1);
                        $status = $update[2] == 1 ? 'AFK' : 'Exit';
                        printf("User %s offline(%s)\n", $user->getName(), $status);
                        break;
                    case LP::FRIEND_ONLINE:
                        $user = $fetchData($update[1] * -1);
                        printf("User %s online\n", $user->getName());
                        break;
                    default:
                        printf("Unknown event %s {%s}\n", $update[0], implode(',', $update));
                        break;
                }
            }
        }
    }

/*
         * @param $id
         * @return Model\User
         */

/*
                 * @var $user Model\User
                 */

LongPoll loop.

@todo make something other than putting data to STDOUT


public function execute()
    {
        $execute = $this->dataString;
        if ($this->requests) {
            foreach ($this->requests as $request) {
                $execute .= ','.$request->dataString;
            }
            $execute = '['.$execute.']';

            if (!$this->callback && !$this->vk->jsCallback) {
                $this->vk->jsCallback = true;
                $oldCallback = $this->vk->callback;

                $this->callback = function ($data) use (&$oldCallback) {
                    $std = new stdClass();
                    $std->response = $data;

                    return new Api($std, $oldCallback);
                };

                $this->vk->createAs($this->callback);
            }
        }

        return $this->vk->request('execute', ['code' => sprintf('return %s;', $execute)]);
    }

public
function
execute
(
)
{
$
execute
=
$
this
->
dataString
;
if
(
$
this
->
requests
)
{
foreach
(
$
this
->
requests
as
$
request
)
{
$
execute
.=
','
.
$
request
->
dataString
;
}
$
execute
=
'['
.
$
execute
.
']'
;
if
(
!
$
this
->
callback
&&
!
$
this
->
vk
->
jsCallback
)
{
$
this
->
vk
->
jsCallback
=
true
;
$
oldCallback
=
$
this
->
vk
->
callback
;
$
this
->
callback
=
function
(
$
data
)
use
(
&
$
oldCallback
)
{
$
std
=
new
stdClass
(
)
;
$
std
->
response
=
$
data
;
return
new
Api
(
$
std
,
$
oldCallback
)
;
}
;
$
this
->
vk
->
createAs
(
$
this
->
callback
)
;
}
}
return
$
this
->
vk
->
request
(
'execute'
,
[
'code'
=>
sprintf
(
'return %s;'
,
$
execute
)
]
)
;
}

We wanna send our current VkJs to Vk execute.

@return RequestTransaction|Api

We wanna send our current VkJs to Vk execute .


public function each(Closure $callback)
    {
        if (!is_callable($callback)) {
            return;
        }
        $data = [];
        $this->items ? $data = &$this->items : (!$this->data ?: $data = &$this->data);
        foreach ($data as $k => $v) {
            call_user_func_array($callback, [$k, $v]);
        }
    }

public function each ( Closure $ callback ) { if ( ! is_callable ( $ callback ) ) { return ; } $ data = [ ] ; $ this -> items ? $ data = & $ this -> items : ( ! $ this -> data ? : $ data = & $ this -> data ) ; foreach ( $ data as $ k => $ v ) { call_user_func_array ( $ callback , [ $ k , $ v ] ) ; } }

This method takes Closure as argument, so every element from response will go into this Closure.

@param Closure $callback

This method takes Closure as argument so every element from response will go into this Closure .


public function get($id = false)
    {
        if (!$id) {
            if (is_array($this->data)) {
                return $this->data[0];
            } elseif (isset($this->items) && $this->items !== false) {
                return $this->items[0];
            } else {
                return $this->data;
            }
        } else {
            return $this->data[$id];
        }
    }

public function get ( $ id = false ) { if ( ! $ id ) { if ( is_array ( $ this -> data ) ) { return $ this -> data [ 0 ] ; } elseif ( isset ( $ this -> items ) && $ this -> items !== false ) { return $ this -> items [ 0 ] ; } else { return $ this -> data ; } } else { return $ this -> data [ $ id ] ; } }

This method will return one element if id is not specified or element of array otherwise.

@param bool|int $id

@return mixed

This method will return one element if id is not specified or element of array otherwise .


public function getSource($id = 0)
    {
        if ($this->copy_history === false) {
            return false;
        }
        if (!isset($this->copy_history[$id])) {
            return false;
        }

        return new self($this->copy_history[0 + $id]);
    }

public function getSource ( $ id = 0 ) { if ( $ this -> copy_history === false ) { return false ; } if ( ! isset ( $ this -> copy_history [ $ id ] ) ) { return false ; } return new self ( $ this -> copy_history [ 0 + $ id ] ) ; }

Return recursive wall instance.

@param int $id

@return bool|Wall


public function fetchData()
    {
        if (!$this->guzzle) {
            $this->guzzle = new \GuzzleHttp\Client();
        }

        $args = $this->args;
        if ($this->accessToken) {
            $args['access_token'] = $this->accessToken;
        }

        if ((empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off') && false !== $this->noHttpsSecret) {
            $args['sig'] = md5('/method/'.$this->methodName.'?'.http_build_query($args).$this->noHttpsSecret);
        }

        $data = $this->guzzle->post(self::URL_VK_API . $this->methodName, ['form_params' => $args])->getBody();
        $data = json_decode($data);
        $c = new Api($data, $this->callback);

        return $c;
    }

public function fetchData ( ) { if ( ! $ this -> guzzle ) { $ this -> guzzle = new \ GuzzleHttp \ Client ( ) ; } $ args = $ this -> args ; if ( $ this -> accessToken ) { $ args [ 'access_token' ] = $ this -> accessToken ; } if ( ( empty ( $ _SERVER [ 'HTTPS' ] ) || $ _SERVER [ 'HTTPS' ] === 'off' ) && false !== $ this -> noHttpsSecret ) { $ args [ 'sig' ] = md5 ( '/method/' . $ this -> methodName . '?' . http_build_query ( $ args ) . $ this -> noHttpsSecret ) ; } $ data = $ this -> guzzle -> post ( self :: URL_VK_API . $ this -> methodName , [ 'form_params' => $ args ] ) -> getBody ( ) ; $ data = json_decode ( $ data ) ; $ c = new Api ( $ data , $ this -> callback ) ; return $ c ; }


public function validateRights($permissions, $bitmask = 0)
    {
        $valid = 0;
        if (is_array($bitmask)) {
            foreach ($bitmask as $bit) {
                $valid = $this->validateRights($permissions, $bit);
            }
        } else {
            $valid = $permissions & $bitmask;
        }

        return $valid;
    }

public function validateRights ( $ permissions , $ bitmask = 0 ) { $ valid = 0 ; if ( is_array ( $ bitmask ) ) { foreach ( $ bitmask as $ bit ) { $ valid = $ this -> validateRights ( $ permissions , $ bit ) ; } } else { $ valid = $ permissions & $ bitmask ; } return $ valid ; }

Used to validate rights.

@param $permissions
@param int|array $bitmask

@return int


public function param($key, $value, $defaultValue = false)
    {
        if (!$value && $defaultValue) {
            $value = $defaultValue;
        }

        $this->params[$key] = $value;

        return $this;
    }

public function param ( $ key , $ value , $ defaultValue = false ) { if ( ! $ value && $ defaultValue ) { $ value = $ defaultValue ; } $ this -> params [ $ key ] = $ value ; return $ this ; }

Set one param.

@param mixed $key
@param mixed $value
@param bool  $defaultValue

@return $this


public function params(array $data)
    {
        foreach ($data as $k => $v) {
            $this->param($k, $v);
        }

        return $this;
    }

public function params ( array $ data ) { foreach ( $ data as $ k => $ v ) { $ this -> param ( $ k , $ v ) ; } return $ this ; }

Set many params.

@param array $data

@return $this


public function request($methodName, $args = false)
    {
        if (is_array($args)) {
            $this->params($args);
        }

        $this->params = array_merge($this->params, $this->systemArgs());

        $d = new RequestTransaction($methodName, $this->params, $this->accessToken, $this->callback, $this->noHttpsSecret);
        $this->reset();

        return $d;
    }

public function request ( $ methodName , $ args = false ) { if ( is_array ( $ args ) ) { $ this -> params ( $ args ) ; } $ this -> params = array_merge ( $ this -> params , $ this -> systemArgs ( ) ) ; $ d = new RequestTransaction ( $ methodName , $ this -> params , $ this -> accessToken , $ this -> callback , $ this -> noHttpsSecret ) ; $ this -> reset ( ) ; return $ d ; }

API Request, will return RequestTransaction.

@param string     $methodName
@param bool|array $args

@return Api|RequestTransaction

API Request will return RequestTransaction .


public function save($data)
    {
        $this->vk
            ->param('album_id', $data->aid)
            ->param('server', $data->server)
            ->param('photos_list', $data->photos_list)
            ->param('hash', $data->hash)
            ->request('photos.save')->execute();
    }

public function save ( $ data ) { $ this -> vk -> param ( 'album_id' , $ data -> aid ) -> param ( 'server' , $ data -> server ) -> param ( 'photos_list' , $ data -> photos_list ) -> param ( 'hash' , $ data -> hash ) -> request ( 'photos.save' ) -> execute ( ) ; }

todo Process response.

@param UploadResponse $data


public function startCallback()
    {
        if (isset($_GET['code'])) {
            $token = $this->getToken($_GET['code']);

            return $token;
        } elseif (isset($_GET['error'])) {
            //blah blah
        }

        return false;
    }

public
function
startCallback
(
)
{
if
(
isset
(
$
_GET
[
'code'
]
)
)
{
$
token
=
$
this
->
getToken
(
$
_GET
[
'code'
]
)
;
return
$
token
;
}
elseif
(
isset
(
$
_GET
[
'error'
]
)
)
{
//blah blah
}
return
false
;
}

Will return token if everything is OK.

@return \getjump\Vk\Response\Auth|bool|string


public function getToken($code)
    {
        if (!$this->guzzle) {
            $this->guzzle = new \GuzzleHttp\Client();
        }

        $uri = sprintf(
            self::URL_ACCESS_TOKEN,
            $this->g('client_id'),
            $this->g('client_secret'),
            $code,
            urlencode($this->g('redirect_uri'))
        );

        $data = $this->guzzle->get($uri)->getBody();
        $data = json_decode($data);

        if (isset($data->access_token)) {
            return new \getjump\Vk\Response\Auth($data->access_token, $data->expires_in, $data->user_id);
        } elseif (isset($data->error)) {
            // ERROR PROCESSING
        }

        return false;
    }

public
function
getToken
(
$
code
)
{
if
(
!
$
this
->
guzzle
)
{
$
this
->
guzzle
=
new
\
GuzzleHttp
\
Client
(
)
;
}
$
uri
=
sprintf
(
self
::
URL_ACCESS_TOKEN
,
$
this
->
g
(
'client_id'
)
,
$
this
->
g
(
'client_secret'
)
,
$
code
,
urlencode
(
$
this
->
g
(
'redirect_uri'
)
)
)
;
$
data
=
$
this
->
guzzle
->
get
(
$
uri
)
->
getBody
(
)
;
$
data
=
json_decode
(
$
data
)
;
if
(
isset
(
$
data
->
access_token
)
)
{
return
new
\
getjump
\
Vk
\
Response
\
Auth
(
$
data
->
access_token
,
$
data
->
expires_in
,
$
data
->
user_id
)
;
}
elseif
(
isset
(
$
data
->
error
)
)
{
// ERROR PROCESSING
}
return
false
;
}

Method converts code to token.

@param $code

@return \getjump\Vk\Response\Auth|bool


private function hitsToItems($instance)
    {
        $items = array();

        foreach ($this->hits['hits'] as $hit) {

            $items[] = $instance->newFromHitBuilder($hit);
        }

        return $items;
    }

private function hitsToItems ( $ instance ) { $ items = array ( ) ; foreach ( $ this -> hits [ 'hits' ] as $ hit ) { $ items [ ] = $ instance -> newFromHitBuilder ( $ hit ) ; } return $ items ; }

Hits To Items

@param   Eloquent model instance $instance
@return  array


public static function searchByQuery($query = null, $aggregations = null, $sourceFields = null, $limit = null, $offset = null, $sort = null)
    {
        $instance = new static;

        $params = $instance->getBasicEsParams(true, true, true, $limit, $offset);

        if ($sourceFields) {
            $params['body']['_source']['include'] = $sourceFields;
        }

        if ($query) {
            $params['body']['query'] = $query;
        }

        if ($aggregations) {
            $params['body']['aggs'] = $aggregations;
        }

        if ($sort) {
            $params['body']['sort'] = $sort;
        }

        $result = $instance->getElasticSearchClient()->search($params);

        return new ResultCollection($result, $instance = new static);
    }

public static function searchByQuery ( $ query = null , $ aggregations = null , $ sourceFields = null , $ limit = null , $ offset = null , $ sort = null ) { $ instance = new static ; $ params = $ instance -> getBasicEsParams ( true , true , true , $ limit , $ offset ) ; if ( $ sourceFields ) { $ params [ 'body' ] [ '_source' ] [ 'include' ] = $ sourceFields ; } if ( $ query ) { $ params [ 'body' ] [ 'query' ] = $ query ; } if ( $ aggregations ) { $ params [ 'body' ] [ 'aggs' ] = $ aggregations ; } if ( $ sort ) { $ params [ 'body' ] [ 'sort' ] = $ sort ; } $ result = $ instance -> getElasticSearchClient ( ) -> search ( $ params ) ; return new ResultCollection ( $ result , $ instance = new static ) ; }

Search By Query

Search with a query array

@param   array $query
@param   array $aggregations
@param   array $sourceFields
@param   int $limit
@param   int $offset
@return  ResultCollection


final public static function replaceAllDotsExceptLastThree(string $string): string
    {
        $countDots = substr_count($string, '.');
        if ($countDots > 3) {
            $stringArray = explode('.', $string);
            $string = '';
            for ($i = 0; $i < $countDots - 3; ++$i) {
                $string .= $stringArray[$i].'_';
            }
            $string .= $stringArray[$countDots - 3].'.'.$stringArray[$countDots - 2].'.'.$stringArray[$countDots - 1].'.'.$stringArray[$countDots];
        }

        return $string;
    }

final public static function replaceAllDotsExceptLastThree ( string $ string ) : string { $ countDots = substr_count ( $ string , '.' ) ; if ( $ countDots > 3 ) { $ stringArray = explode ( '.' , $ string ) ; $ string = '' ; for ( $ i = 0 ; $ i < $ countDots - 3 ; ++ $ i ) { $ string .= $ stringArray [ $ i ] . '_' ; } $ string .= $ stringArray [ $ countDots - 3 ] . '.' . $ stringArray [ $ countDots - 2 ] . '.' . $ stringArray [ $ countDots - 1 ] . '.' . $ stringArray [ $ countDots ] ; } return $ string ; }

Will convert "object_something.cool.today.midday" TO "object_something.cool.today.midday".
Will convert "object.something.cool.today" TO "object.something.cool.today".
Will convert "object.something.cool" TO "object.something.cool".
Will convert "object.something" TO "object.something".
Will convert "object" TO "object".

@param string $string

@return string

Will convert object_something . cool . today . midday TO object_something . cool . today . midday . Will convert object . something . cool . today TO object . something . cool . today . Will convert object . something . cool TO object . something . cool . Will convert object . something TO object . something . Will convert object TO object .


final public static function replaceAllDotsExceptLastTwo(string $string): string
    {
        $countDots = substr_count($string, '.');
        if ($countDots > 2) {
            $stringArray = explode('.', $string);
            $string = '';
            for ($i = 0; $i < $countDots - 2; ++$i) {
                $string .= $stringArray[$i].'_';
            }
            $string .= $stringArray[$countDots - 2].'.'.$stringArray[$countDots - 1].'.'.$stringArray[$countDots];
        }

        return $string;
    }

final public static function replaceAllDotsExceptLastTwo ( string $ string ) : string { $ countDots = substr_count ( $ string , '.' ) ; if ( $ countDots > 2 ) { $ stringArray = explode ( '.' , $ string ) ; $ string = '' ; for ( $ i = 0 ; $ i < $ countDots - 2 ; ++ $ i ) { $ string .= $ stringArray [ $ i ] . '_' ; } $ string .= $ stringArray [ $ countDots - 2 ] . '.' . $ stringArray [ $ countDots - 1 ] . '.' . $ stringArray [ $ countDots ] ; } return $ string ; }

Will convert "object.something.cool.today" TO "object_something.cool.today".
Will convert "object.something.cool" TO "object.something.cool".
Will convert "object.something" TO "object.something".
Will convert "object" TO "object".

@param string $string

@return string

Will convert object . something . cool . today TO object_something . cool . today . Will convert object . something . cool TO object . something . cool . Will convert object . something TO object . something . Will convert object TO object .


final public static function replaceAllDotsExceptLast(string $string): string
    {
        $countDots = substr_count($string, '.');
        if ($countDots > 1) {
            $stringArray = explode('.', $string);
            $string = '';
            for ($i = 0; $i < $countDots - 1; ++$i) {
                $string .= $stringArray[$i].'_';
            }
            $string .= $stringArray[$countDots - 1].'.'.$stringArray[$countDots];
        }

        return $string;
    }

final public static function replaceAllDotsExceptLast ( string $ string ) : string { $ countDots = substr_count ( $ string , '.' ) ; if ( $ countDots > 1 ) { $ stringArray = explode ( '.' , $ string ) ; $ string = '' ; for ( $ i = 0 ; $ i < $ countDots - 1 ; ++ $ i ) { $ string .= $ stringArray [ $ i ] . '_' ; } $ string .= $ stringArray [ $ countDots - 1 ] . '.' . $ stringArray [ $ countDots ] ; } return $ string ; }

Will convert "object.something.cool.today" TO "object_something_cool.today".
Will convert "object.something.cool" TO "object_something.cool".
Will convert "object.something" TO "object.something".
Will convert "object" TO "object".

@param string $string

@return string

Will convert object . something . cool . today TO object_something_cool . today . Will convert object . something . cool TO object_something . cool . Will convert object . something TO object . something . Will convert object TO object .


public static function convertIntlFormaterToMalot($formatter)
    {
        $intlToMalot = array_combine(self::$intlFormater, self::$malotFormater);

        $patterns = preg_split('([\\\/.:_;,\s-\ ]{1})', $formatter);
        $exits = array();

        foreach ($patterns as $val) {
            if (isset($intlToMalot[$val])){
                $exits[$val] = $intlToMalot[$val];
            } else {
                // it can throw an Exception
                $exits[$val] = $val;
            }
        }

        return str_replace(array_keys($exits), array_values($exits), $formatter);
    }

public
static
function
convertIntlFormaterToMalot
(
$
formatter
)
{
$
intlToMalot
=
array_combine
(
self
::
$
intlFormater
,
self
::
$
malotFormater
)
;
$
patterns
=
preg_split
(
'([\\\/.:_;,\s-\ ]{1})'
,
$
formatter
)
;
$
exits
=
array
(
)
;
foreach
(
$
patterns
as
$
val
)
{
if
(
isset
(
$
intlToMalot
[
$
val
]
)
)
{
$
exits
[
$
val
]
=
$
intlToMalot
[
$
val
]
;
}
else
{
// it can throw an Exception
$
exits
[
$
val
]
=
$
val
;
}
}
return
str_replace
(
array_keys
(
$
exits
)
,
array_values
(
$
exits
)
,
$
formatter
)
;
}

Convert the PHP date format to Bootstrap Datetimepicker date format


public static function convertMalotToIntlFormater($formatter)
    {
        $malotToIntl = array_combine(self::$malotFormater, self::$intlFormater);

        $patterns = preg_split('([\\\/.:_;,\s-\ ]{1})', $formatter);
        $exits = array();

        foreach ($patterns as $val) {
            if (isset($malotToIntl[$val])){
                $exits[$val] = $malotToIntl[$val];
            } else {
                // it can throw an Exception
                $exits[$val] = $val;
            }
        }

        return str_replace(array_keys($exits), array_values($exits), $formatter);
    }

public
static
function
convertMalotToIntlFormater
(
$
formatter
)
{
$
malotToIntl
=
array_combine
(
self
::
$
malotFormater
,
self
::
$
intlFormater
)
;
$
patterns
=
preg_split
(
'([\\\/.:_;,\s-\ ]{1})'
,
$
formatter
)
;
$
exits
=
array
(
)
;
foreach
(
$
patterns
as
$
val
)
{
if
(
isset
(
$
malotToIntl
[
$
val
]
)
)
{
$
exits
[
$
val
]
=
$
malotToIntl
[
$
val
]
;
}
else
{
// it can throw an Exception
$
exits
[
$
val
]
=
$
val
;
}
}
return
str_replace
(
array_keys
(
$
exits
)
,
array_values
(
$
exits
)
,
$
formatter
)
;
}

Convert the Bootstrap Datetimepicker date format to PHP date format


private function addPicker(ArrayNodeDefinition $rootNode)
    {
        $rootNode
            ->children()
                ->arrayNode('picker')
                    ->canBeUnset()
                    ->addDefaultsIfNotSet()
                    ->treatNullLike(array('enabled' => true))
                    ->treatTrueLike(array('enabled' => true))
                    ->children()
                        ->booleanNode('enabled')->defaultTrue()->end()
                        ->arrayNode('configs')
                            ->addDefaultsIfNotSet()
                            ->children()
                                ->enumNode('formatter')->defaultValue('js')
                                    ->values(array('js', 'php'))
                                ->end()
                            ->end()
                        ->end()
                    ->end()
                ->end()
            ->end()
        ;
    }

private function addPicker ( ArrayNodeDefinition $ rootNode ) { $ rootNode -> children ( ) -> arrayNode ( 'picker' ) -> canBeUnset ( ) -> addDefaultsIfNotSet ( ) -> treatNullLike ( array ( 'enabled' => true ) ) -> treatTrueLike ( array ( 'enabled' => true ) ) -> children ( ) -> booleanNode ( 'enabled' ) -> defaultTrue ( ) -> end ( ) -> arrayNode ( 'configs' ) -> addDefaultsIfNotSet ( ) -> children ( ) -> enumNode ( 'formatter' ) -> defaultValue ( 'js' ) -> values ( array ( 'js' , 'php' ) ) -> end ( ) -> end ( ) -> end ( ) -> end ( ) -> end ( ) -> end ( ) ; }

Add configuration Picker

@param ArrayNodeDefinition $rootNode


private function bindAlexaRequest(Request $request)
    {
        $this->app->singleton('alexa.request', function($app) use ($request) {
            /** @var AlexaRequest $alexaRequest */
            $alexaRequest = AlexaRequest::capture();

            if (!$app['config']['alexa.prompt.enable'] || $alexaRequest->getIntent() !== $app['config']['alexa.prompt.response_intent'] || is_null($alexaRequest->getPromptResponseIntent())) {
                return $alexaRequest;
            } else{
                $alexaRequest->setPromptResponse(true);

                return $alexaRequest;
            }
        });
    }

private
function
bindAlexaRequest
(
Request
$
request
)
{
$
this
->
app
->
singleton
(
'alexa.request'
,
function
(
$
app
)
use
(
$
request
)
{
/** @var AlexaRequest $alexaRequest */
$
alexaRequest
=
AlexaRequest
::
capture
(
)
;
if
(
!
$
app
[
'config'
]
[
'alexa.prompt.enable'
]
||
$
alexaRequest
->
getIntent
(
)
!==
$
app
[
'config'
]
[
'alexa.prompt.response_intent'
]
||
is_null
(
$
alexaRequest
->
getPromptResponseIntent
(
)
)
)
{
return
$
alexaRequest
;
}
else
{
$
alexaRequest
->
setPromptResponse
(
true
)
;
return
$
alexaRequest
;
}
}
)
;
}

Bind the appropriate AlexaResponse type to the IoC container


protected function registerMiddleware()
    {
        $this->app->singleton(\Develpr\AlexaApp\Http\Middleware\Request::class, function ($app) {
            return new \Develpr\AlexaApp\Http\Middleware\Request($app, $app['alexa.router'], $app['alexa.request'], $app['alexa.router.middleware']);
        });

        $this->app->singleton(\Develpr\AlexaApp\Http\Middleware\Certificate::class, function ($app) {
            return new \Develpr\AlexaApp\Http\Middleware\Certificate($app['alexa.request'], $app['alexa.certificateProvider'], $app['config']['alexa']);
        });
    }

protected function registerMiddleware ( ) { $ this -> app -> singleton ( \ Develpr \ AlexaApp \ Http \ Middleware \ Request :: class , function ( $ app ) { return new \ Develpr \ AlexaApp \ Http \ Middleware \ Request ( $ app , $ app [ 'alexa.router' ] , $ app [ 'alexa.request' ] , $ app [ 'alexa.router.middleware' ] ) ; } ) ; $ this -> app -> singleton ( \ Develpr \ AlexaApp \ Http \ Middleware \ Certificate :: class , function ( $ app ) { return new \ Develpr \ AlexaApp \ Http \ Middleware \ Certificate ( $ app [ 'alexa.request' ] , $ app [ 'alexa.certificateProvider' ] , $ app [ 'config' ] [ 'alexa' ] ) ; } ) ; }


public function resume()
    {
        $token = $this->context('AudioPlayer.token');
        $url = cache($token);
        $offset = $this->context('AudioPlayer.offsetInMilliseconds');
        return $this->play($url, $token, $offset);
    }

public function resume ( ) { $ token = $ this -> context ( 'AudioPlayer.token' ) ; $ url = cache ( $ token ) ; $ offset = $ this -> context ( 'AudioPlayer.offsetInMilliseconds' ) ; return $ this -> play ( $ url , $ token , $ offset ) ; }

Resumes from the previous position

@return AlexaResponse


public function request()
    {
        if (!isset($this->alexaRequest)) {
            $this->alexaRequest = function_exists('app') ?
                app(AlexaRequest::class) : new AlexaRequest();
        }

        return $this->alexaRequest;
    }

public function request ( ) { if ( ! isset ( $ this -> alexaRequest ) ) { $ this -> alexaRequest = function_exists ( 'app' ) ? app ( AlexaRequest :: class ) : new AlexaRequest ( ) ; } return $ this -> alexaRequest ; }

Get the alexa request

@return AlexaRequest


protected function addRequestMiddlewareToBeginning(ReflectionClass $reflection)
    {
        $property = $reflection->getProperty('middleware');
        $property->setAccessible(true);

        $middleware = $property->getValue($this->app);

        array_unshift($middleware, 'Develpr\AlexaApp\Http\Middleware\Request');

        $property->setValue($this->app, $middleware);
        $property->setAccessible(false);
    }

Add the request middleware to the beginning of the middleware stack on the
Lumen application instance.

@param \ReflectionClass $reflection

Add the request middleware to the beginning of the middleware stack on the Lumen application instance .


public function matches(Route $route, Request $request)
    {
        // If this isn't an Alexa Route then it doesn't match!
        if (!$route instanceof AlexaRoute) {
            return false;
        }

        if (!$request->isPromptResponse()) {
            return ($request->getRequestType() . $request->getIntent() == $route->getRouteIntent());
        } else {
            return ($request->getRequestType() . $request->getPromptResponseIntent() == $route->getRouteIntent());
        }
    }

Validate a given rule against a route and request.

@param  \Develpr\AlexaApp\Http\Routing\AlexaRoute $route
@param  \Develpr\AlexaApp\Request\AlexaRequest    $request

@return bool

Validate a given rule against a route and request .


protected function newAlexaRoute($methods, $uri, $intent, $action)
    {
        return (new AlexaRoute($methods, $uri, $intent, $action))->setContainer($this->container)->setRouter($this);
    }

protected function newAlexaRoute ( $ methods , $ uri , $ intent , $ action ) { return ( new AlexaRoute ( $ methods , $ uri , $ intent , $ action ) ) -> setContainer ( $ this -> container ) -> setRouter ( $ this ) ; }

Create a new Route object.

@param array|string               $methods
@param string                     $uri
@param string                     $intent
@param \Closure|array|string|null $action

@return \Illuminate\Routing\Route


public function getSessionValue($key = null)
    {
        return array_key_exists($key, $this->getSession()) ? $this->getSession()[$key] : null;
    }

public function getSessionValue ( $ key = null ) { return array_key_exists ( $ key , $ this -> getSession ( ) ) ? $ this -> getSession ( ) [ $ key ] : null ; }

Get a particular session value by key

@param string $key

@return mixed|null


public function updateSlot($slotName, $value, $confirmed = null)
    {
        if (!$this->processed) {
            $this->process();
        }

        if (array_has($this->slots, [$slotName])) {
            $this->slots[$slotName]['value'] = $value;

            if ($confirmed) {
                $this->slots[$slotName]['confirmationStatus'] = $this::CONFIRMED_STATUS;
            } elseif (!is_null($confirmed) && !$confirmed) {
                $this->slots[$slotName]['confirmationStatus'] = $this::DENIED_STATUS;
            } else {
                $this->slots[$slotName]['confirmationStatus'] = $this::NO_CONFIRMATION_STATUS;
            }
        }

        return $this;
    }

public function updateSlot ( $ slotName , $ value , $ confirmed = null ) { if ( ! $ this -> processed ) { $ this -> process ( ) ; } if ( array_has ( $ this -> slots , [ $ slotName ] ) ) { $ this -> slots [ $ slotName ] [ 'value' ] = $ value ; if ( $ confirmed ) { $ this -> slots [ $ slotName ] [ 'confirmationStatus' ] = $ this :: CONFIRMED_STATUS ; } elseif ( ! is_null ( $ confirmed ) && ! $ confirmed ) { $ this -> slots [ $ slotName ] [ 'confirmationStatus' ] = $ this :: DENIED_STATUS ; } else { $ this -> slots [ $ slotName ] [ 'confirmationStatus' ] = $ this :: NO_CONFIRMATION_STATUS ; } } return $ this ; }

Update a slot

@param $slotName
@param $value
@param bool $confirmed
@param bool $denied

@return $this


public static function getValidators()
    {
        $validators = parent::getValidators();

        foreach ($validators as $key => $validator) {
            if ($validator instanceof UriValidator) {
                break;
            }
        }

        $validators[] = new AlexaValidator;

        return $validators;
    }

public static function getValidators ( ) { $ validators = parent :: getValidators ( ) ; foreach ( $ validators as $ key => $ validator ) { if ( $ validator instanceof UriValidator ) { break ; } } $ validators [ ] = new AlexaValidator ; return $ validators ; }

Get the route validators for the instance.

@return array

Get the route validators for the instance .


protected function compileRoute()
    {
        if (version_compare(\Illuminate\Foundation\Application::VERSION, '5.5.0') < 0) {
            if ( is_callable( "parent::extractOptionalParameters" ) ) {
                return parent::compileRoute();
            }
        }

        if (! $this->compiled) {

            //todo: this is a bit ugly - we should go deeper and solve the real problem
            //This is ugly - before 5.4, we didn't use "uri()" method in the RouteCompiler (there was no
            //route compiler!), and instead we used the private uri instance variable. Which meant that
            //`uri()` and `uri` were different.
            $tempRouterIntent = $this->routeIntent;
            $this->routeIntent = "";
            $this->compiled = (new RouteCompiler($this))->compile();
            $this->routeIntent = $tempRouterIntent;
        }

        return $this->compiled;
    }

Compile the route into a Symfony CompiledRoute instance.

@return void

Compile the route into a Symfony CompiledRoute instance .


private function getCertificate(IlluminateRequest $request)
    {
        $signatureChainUri = $request->header(self::CERTIFICATE_URL_HEADER);

        $this->validateKeychainUri($signatureChainUri);

        $certificate = $this->certificateProvider->getCertificateFromUri($signatureChainUri);

        return $certificate;
    }

private function getCertificate ( IlluminateRequest $ request ) { $ signatureChainUri = $ request -> header ( self :: CERTIFICATE_URL_HEADER ) ; $ this -> validateKeychainUri ( $ signatureChainUri ) ; $ certificate = $ this -> certificateProvider -> getCertificateFromUri ( $ signatureChainUri ) ; return $ certificate ; }

Get the certificate from the certificate provider

@param IlluminateRequest $request

@return mixed


private function prepareResponseData()
    {
        $responseData = [];
        $responseData['version'] = self::ALEXA_RESPONSE_VERSION;
        $response = [];

        //Check to see if a speech, card, or reprompt object are set and if so
        //add them to the data object
        if (!is_null($this->speech) && $this->speech instanceof OutputSpeech) {
            $response = $this->speech->toArray();
        }

        if (!is_null($this->card) && $this->card instanceof Card) {
            $response['card'] = $this->card->toArray();
        }

        if (!is_null($this->reprompt) && $this->reprompt instanceof Reprompt && trim($this->reprompt->getValue()) != "") {
            $response['reprompt'] = $this->reprompt->toArray();
        }

        if (!is_null($this->directives)) {
            foreach ($this->directives as $directive) {
                $response['directives'][] = $directive->toArray();
            }
        }

        $response['shouldEndSession'] = $this->shouldSessionEnd;

        $sessionAttributes = $this->getSessionData();

        if ($sessionAttributes && count($sessionAttributes) > 0) {
            $responseData['sessionAttributes'] = $sessionAttributes;
        }

        $responseData['response'] = $response;

        return $responseData;
    }

Build the valid Alexa response object

@return array


protected function sendRequestThroughRouter($request)
    {
        $this->app->instance('request', $request);

        return (new Pipeline($this->app))->send($request)->through($this->middleware)->then(function ($request) {
            return $this->router->dispatch($this->alexaRequest);
        });
    }

protected function sendRequestThroughRouter ( $ request ) { $ this -> app -> instance ( 'request' , $ request ) ; return ( new Pipeline ( $ this -> app ) ) -> send ( $ request ) -> through ( $ this -> middleware ) -> then ( function ( $ request ) { return $ this -> router -> dispatch ( $ this -> alexaRequest ) ; } ) ; }

Send through our custom router

@param $request

@return Response


protected function gatherAppMiddleware(Kernel $kernel)
    {
        $reflection = new ReflectionClass($kernel);

        $property = $reflection->getProperty('middleware');
        $property->setAccessible(true);

        $middleware = $property->getValue($kernel);

        if ($this->app['config']['alexa.skipCsrfCheck']) {
            $middleware = $this->unsetCsrfMiddleware($middleware);
        }

        return $middleware;
    }

protected function gatherAppMiddleware ( Kernel $ kernel ) { $ reflection = new ReflectionClass ( $ kernel ) ; $ property = $ reflection -> getProperty ( 'middleware' ) ; $ property -> setAccessible ( true ) ; $ middleware = $ property -> getValue ( $ kernel ) ; if ( $ this -> app [ 'config' ] [ 'alexa.skipCsrfCheck' ] ) { $ middleware = $ this -> unsetCsrfMiddleware ( $ middleware ) ; } return $ middleware ; }

Gather the application middleware besides this one so that we can send
our request through them, exactly how the developer wanted.

@param \Illuminate\Contracts\Http\Kernel $kernel

@return array

Gather the application middleware besides this one so that we can send our request through them exactly how the developer wanted .


protected function persistCertificate($certificateChainUri, $certificateContents)
    {
        $this->filesystem->put($this->calculateFilePath($certificateChainUri), $certificateContents);
    }

protected function persistCertificate ( $ certificateChainUri , $ certificateContents ) { $ this -> filesystem -> put ( $ this -> calculateFilePath ( $ certificateChainUri ) , $ certificateContents ) ; }

Persist the certificate contents to data store so it's retrievable using the certificate chain uri

@param string $certificateChainUri
@param string $certificateContents

Persist the certificate contents to data store so it s retrievable using the certificate chain uri


protected function retrieveCertificateFromStore($certificateChainUri)
    {
        try {
            $certificateChain = $this->filesystem->get($this->calculateFilePath($certificateChainUri));
        } catch (FileNotFoundException $e) {
            $certificateChain = null;
        }

        return $certificateChain;
    }

protected function retrieveCertificateFromStore ( $ certificateChainUri ) { try { $ certificateChain = $ this -> filesystem -> get ( $ this -> calculateFilePath ( $ certificateChainUri ) ) ; } catch ( FileNotFoundException $ e ) { $ certificateChain = null ; } return $ certificateChain ; }

Retrieve the certificate give the certificate chain's uri from the datastore

@param string $certificateChainUri

@return string|null

Retrieve the certificate give the certificate chain s uri from the datastore


private function calculateFilePath($certificateChainUri)
    {
        $filename = md5($certificateChainUri);

        $path = $this->filePath.$filename;

        return $path;
    }

private function calculateFilePath ( $ certificateChainUri ) { $ filename = md5 ( $ certificateChainUri ) ; $ path = $ this -> filePath . $ filename ; return $ path ; }

Calculate the path that the certificate should be stored

@param string $certificateChainUri

@return string


public function setCustomProtectedWords(array $words)
	{
		$this->customProtectedWords = [];
		foreach ($words as $word) {
			$this->customProtectedWords[] = Stringy::create($word)->trim();
		}
	}

public function setCustomProtectedWords ( array $ words ) { $ this -> customProtectedWords = [ ] ; foreach ( $ words as $ word ) { $ this -> customProtectedWords [ ] = Stringy :: create ( $ word ) -> trim ( ) ; } }

Trims whitespace from the given words, and assigns the
array to the "custom protected words" property.

@param string[] $words

Trims whitespace from the given words and assigns the array to the custom protected words property .


public function capitalize($string)
	{
		$string = $this->normalizeInput($string);
		$parts = $this->splitStringIntoParts($string);
		$parts = $this->processStringParts($parts);
		$parts = $this->processFirstSentenceWordsInParts($parts);
		$parts = $this->processLastWordInParts($parts);
		return $this->joinStringParts($parts);
	}

public function capitalize ( $ string ) { $ string = $ this -> normalizeInput ( $ string ) ; $ parts = $ this -> splitStringIntoParts ( $ string ) ; $ parts = $ this -> processStringParts ( $ parts ) ; $ parts = $ this -> processFirstSentenceWordsInParts ( $ parts ) ; $ parts = $ this -> processLastWordInParts ( $ parts ) ; return $ this -> joinStringParts ( $ parts ) ; }

Capitalizes the given string, according to AP rules.

@param string $string

@return string

Capitalizes the given string according to AP rules .


protected function normalizeInput($string)
	{
		$string = Stringy::create($string)->collapseWhitespace();
		$string = $this->normalizeInputPunctuation($string->__toString());
		return Stringy::create($string);
	}

protected function normalizeInput ( $ string ) { $ string = Stringy :: create ( $ string ) -> collapseWhitespace ( ) ; $ string = $ this -> normalizeInputPunctuation ( $ string -> __toString ( ) ) ; return Stringy :: create ( $ string ) ; }

Normalises the given string, ready for capitalisation.

@param string $string

@return string

Normalises the given string ready for capitalisation .


protected function processStringParts(array $parts)
	{
		array_walk($parts, function (&$part) {
			$part = $this->isWordLike($part) ? $this->processWord($part) : $part;
		});
		return $parts;
	}

protected function processStringParts ( array $ parts ) { array_walk ( $ parts , function ( & $ part ) { $ part = $ this -> isWordLike ( $ part ) ? $ this -> processWord ( $ part ) : $ part ; } ) ; return $ parts ; }

Processes the given array of string parts.

@param array $parts

@return array

Processes the given array of string parts .


protected function processFirstSentenceWordsInParts(array $parts)
	{
		$length = count($parts);
		$isFirst = true;
		for ($index = 0; $index < $length; $index++) {
			$part = $parts[$index];
			if ($this->isWordLike($part)) {
				if ($isFirst) {
					$parts[$index] = $this->processFirstLastWord($part);
					$isFirst = false;
				}
				continue;
			}
			if ($this->isSentenceDelimiter($part)) {
				$isFirst = true;
			}
		}
		return $parts;
	}

protected function processFirstSentenceWordsInParts ( array $ parts ) { $ length = count ( $ parts ) ; $ isFirst = true ; for ( $ index = 0 ; $ index < $ length ; $ index ++ ) { $ part = $ parts [ $ index ] ; if ( $ this -> isWordLike ( $ part ) ) { if ( $ isFirst ) { $ parts [ $ index ] = $ this -> processFirstLastWord ( $ part ) ; $ isFirst = false ; } continue ; } if ( $ this -> isSentenceDelimiter ( $ part ) ) { $ isFirst = true ; } } return $ parts ; }

Processes the first words in any sentences within the given array of
parts.

@param array $parts

@return array

Processes the first words in any sentences within the given array of parts .


protected function processLastWordInParts(array $parts)
	{
		$parts = array_reverse($parts);
		$length = count($parts);
		for ($index = 0; $index < $length; $index++) {
			$part = $parts[$index];
			if ($this->isWordLike($part)) {
				$parts[$index] = $this->processFirstLastWord($part);
				break;
			}
		}
		return array_reverse($parts);
	}

protected function processLastWordInParts ( array $ parts ) { $ parts = array_reverse ( $ parts ) ; $ length = count ( $ parts ) ; for ( $ index = 0 ; $ index < $ length ; $ index ++ ) { $ part = $ parts [ $ index ] ; if ( $ this -> isWordLike ( $ part ) ) { $ parts [ $ index ] = $ this -> processFirstLastWord ( $ part ) ; break ; } } return array_reverse ( $ parts ) ; }

Processes the last word-like item in the given array of parts.

@param array $parts

@return array

Processes the last word - like item in the given array of parts .


protected function processWord($word)
	{
		if ($this->isStandardProtectedWord($word)) {
			return $this->lowercaseWord($word);
		}
		if ($this->isCustomProtectedWord($word)) {
			return $word;
		}
		return $this->capitalizeWord($word);
	}

protected function processWord ( $ word ) { if ( $ this -> isStandardProtectedWord ( $ word ) ) { return $ this -> lowercaseWord ( $ word ) ; } if ( $ this -> isCustomProtectedWord ( $ word ) ) { return $ word ; } return $ this -> capitalizeWord ( $ word ) ; }

Processes the given word.

@param string $word

@return string


protected function replacePattern($string, $pattern, $replacement)
	{
		$replaced = preg_replace($pattern, $replacement, $string);
		return is_null($replaced) ? $string : $replaced;
	}

protected function replacePattern ( $ string , $ pattern , $ replacement ) { $ replaced = preg_replace ( $ pattern , $ replacement , $ string ) ; return is_null ( $ replaced ) ? $ string : $ replaced ; }

Replaces all matches of the given regular expression pattern in the
given string with the given replacement. If an error occurs, returns the
original string.

// TODO: Make `replacePattern` multi-byte safe

@param string $string
@param string $pattern
@param string $replacement

@return string

Replaces all matches of the given regular expression pattern in the given string with the given replacement . If an error occurs returns the original string .


public function get_pro_suffix($name)
	{

		$found_suffix_arr = array();
		foreach ($this->dict['suffixes']['prof'] as $suffix) {
			if (preg_match('/[,\s]+' . preg_quote($suffix) . '\b/i', $name, $matches)) {
				$found_suffix = trim($matches[0]);
				$found_suffix = rtrim($found_suffix, ',');
				$found_suffix = ltrim($found_suffix, ',');
				$found_suffix_arr[] = trim($found_suffix);
			}
		}
		return $found_suffix_arr;
	}

public function get_pro_suffix ( $ name ) { $ found_suffix_arr = array ( ) ; foreach ( $ this -> dict [ 'suffixes' ] [ 'prof' ] as $ suffix ) { if ( preg_match ( '/[,\s]+' . preg_quote ( $ suffix ) . '\b/i' , $ name , $ matches ) ) { $ found_suffix = trim ( $ matches [ 0 ] ) ; $ found_suffix = rtrim ( $ found_suffix , ',' ) ; $ found_suffix = ltrim ( $ found_suffix , ',' ) ; $ found_suffix_arr [ ] = trim ( $ found_suffix ) ; } } return $ found_suffix_arr ; }

Checks for the existence of, and returns professional suffix

@param string $name the name you wish to test
@return mixed returns the suffix if exists, false otherwise

Checks for the existence of and returns professional suffix


public function break_words($name)
	{
		$temp_word_arr = explode(' ', $name);
		$final_word_arr = array();
		foreach ($temp_word_arr as $key => $word) {
			if ($word != "" && $word != ",") {
				$final_word_arr[] = $word;
			}
		}
		return $final_word_arr;
	}

public
function
break_words
(
$
name
)
{
$
temp_word_arr
=
explode
(
' '
,
$
name
)
;
$
final_word_arr
=
array
(
)
;
foreach
(
$
temp_word_arr
as
$
key
=>
$
word
)
{
if
(
$
word
!=
""
&&
$
word
!=
","
)
{
$
final_word_arr
[
]
=
$
word
;
}
}
return
$
final_word_arr
;
}

Breaks name into individual words

@param string $name the full name you wish to parse
@return array full list of words broken down by spaces


protected function is_salutation($word)
	{
		$word = str_replace('.', '', mb_strtolower($word));
		foreach ($this->dict['prefix'] as $replace => $originals) {
			if (in_array($word, $originals)) {
				return $replace;
			}
		}
		return false;
	}

protected function is_salutation ( $ word ) { $ word = str_replace ( '.' , '' , mb_strtolower ( $ word ) ) ; foreach ( $ this -> dict [ 'prefix' ] as $ replace => $ originals ) { if ( in_array ( $ word , $ originals ) ) { return $ replace ; } } return false ; }

Checks word against list of common honorific prefixes

@param string $word the single word you wish to test
@return boolean


protected function is_line_suffix($word, $name)
	{

		# Ignore periods and righ commas, normalize case
		$word = str_replace('.', '', mb_strtolower($word));
		$word = rtrim($word, ',');

		# Search the array for our word
		$line_match = array_search($word, array_map('mb_strtolower', $this->dict['suffixes']['line']));

		# Now test our edge cases based on lineage
		if ($line_match !== false) {
			# Store our match
			$matched_case = $this->dict['suffixes']['line'][$line_match];

			# Remove it from the array
			$temp_array = $this->dict['suffixes']['line'];
			unset($temp_array[$line_match]);

			# Make sure we're dealing with the suffix and not a surname
			if ($word == 'senior' || $word == 'junior') {

				# If name is Joshua Senior, it's pretty likely that Senior is the surname
				# However, if the name is Joshua Jones Senior, then it's likely a suffix
				if ($this->mb_str_word_count($name) < 3) {
					return false;
				}

				# If the word Junior or Senior is contained, but so is some other
				# lineage suffix, then the word is likely a surname and not a suffix
				foreach ($temp_array as $suffix) {
					if (preg_match("/\b" . $suffix . "\b/i", $name)) {
						return false;
					}
				}
			}
			return $matched_case;
		}
		return false;
	}

Checks word against array of common lineage suffixes

@param string $word the single word you wish to test
@param string $name full name for context in determining edge-cases
@return mixed boolean if false, string if true (returns suffix)


public function generateEmojiPhpConstants()
	{

		$data = json_decode(file_get_contents(Wordsmith::$plugin->getBasePath() . '/libs/emoji.json'));

		$data = array_map(
			function($entry){

				$assumedName = !empty($entry->name) ? $entry->name : (string) Stringy::create($entry->short_name)->humanize()->toUpperCase();
				$constantName = (string) Stringy::create($assumedName)->toLowerCase()->replace('&', 'AND')->slugify('_')->toUpperCase();

				$char = '';
				foreach (explode('-', $entry->unified) as $code)
				{
					$char .= '\u{' . $code . '}';
				}

				return [
					'constantName' => $constantName,
					'unicode' => $char,
				];
			},
			$data
		);

		$output = '';

		foreach ($data as $emoji)
		{
			$output .= "\n" . "const {$emoji['constantName']} = \"{$emoji['unicode']}\";";
		}

		return $output;

	}

For internal use only.

We use this function to reformat data from the source-of-truth JSON in order to create the code for \libs\Emoji.php

@return string


public function chop($s, $limit = 1, $unit = 'p', $append = null, $allowedTags = null) : string
	{
		return (new Hacksaw())->chop($s, $limit, $unit, $append, $allowedTags);
	}

public function chop ( $ s , $ limit = 1 , $ unit = 'p' , $ append = null , $ allowedTags = null ) : string { return ( new Hacksaw ( ) ) -> chop ( $ s , $ limit , $ unit , $ append , $ allowedTags ) ; }

Helps chop your content down to a manageable size.

@param $s
@param int $limit
@param string $unit
@param null $append
@param null $allowedTags
@return string

Helps chop your content down to a manageable size .


public function emojify($s, $name_delimiter=':', $emoticon_delimiter='') : string
	{
		return Wordsmith::$plugin->emoji->emojify($s, $name_delimiter, $name_delimiter, $emoticon_delimiter, $emoticon_delimiter);
	}

public function emojify ( $ s , $ name_delimiter = ':' , $ emoticon_delimiter = '' ) : string { return Wordsmith :: $ plugin -> emoji -> emojify ( $ s , $ name_delimiter , $ name_delimiter , $ emoticon_delimiter , $ emoticon_delimiter ) ; }

Replaces emoticons and Emoji name codes in text with their actual Unicode Emoji characters.

@param $s
@param string $name_delimiter
@param string $emoticon_delimiter

@return string

Replaces emoticons and Emoji name codes in text with their actual Unicode Emoji characters .


public function firstWord($s)
	{
		if (empty($s))
		{
			return null;
		}
		return (Stringy::create($s)->collapseWhitespace()->split(' ', 2))[0];
	}

public
function
firstWord
(
$
s
)
{
if
(
empty
(
$
s
)
)
{
return
;
}
return
(
Stringy
::
create
(
$
s
)
->
collapseWhitespace
(
)
->
split
(
' '
,
2
)
)
[
0
]
;
}

Returns the first word in the string, or an empty string if the source string is empty.

@param $s
@return string|null

Returns the first word in the string or an empty string if the source string is empty .


public function isStringy($thingy) : bool
    {
        return (
            is_string($thingy)
            || is_numeric($thingy)
            || (is_object($thingy) && method_exists($thingy, '__toString' ))
        );
    }

public function isStringy ( $ thingy ) : bool { return ( is_string ( $ thingy ) || is_numeric ( $ thingy ) || ( is_object ( $ thingy ) && method_exists ( $ thingy , '__toString' ) ) ) ; }

Returns whether a thingy is stringy.

Thingies that are stringy include: a string, a printable number, or a string-castable object

@param $thingy
@return bool


public function lastWord($s)
	{
		if (empty($s))
		{
			return null;
		}
		$words = Stringy::create($s)->collapseWhitespace()->split(' ');
		return (string) current(end($words));
	}

public
function
lastWord
(
$
s
)
{
if
(
empty
(
$
s
)
)
{
return
;
}
$
words
=
Stringy
::
create
(
$
s
)
->
collapseWhitespace
(
)
->
split
(
' '
)
;
return
(
string
)
current
(
end
(
$
words
)
)
;
}

Returns the last word in the string, or an empty string if the source string is empty.

@param $s
@return string|null

Returns the last word in the string or an empty string if the source string is empty .


public function lowerCaseRoman($s, $matchMode = 'strict') : string
	{
		$result = RomanNumerals::romanNumeralMatchCallback(
			$s,
			$matchMode,
			function (array $matches) {
				if (empty($matches[1])) {
					return $matches[1];
				}
				return strtolower($matches[1]);
			}
		);
		return $result;
	}

public function lowerCaseRoman ( $ s , $ matchMode = 'strict' ) : string { $ result = RomanNumerals :: romanNumeralMatchCallback ( $ s , $ matchMode , function ( array $ matches ) { if ( empty ( $ matches [ 1 ] ) ) { return $ matches [ 1 ] ; } return strtolower ( $ matches [ 1 ] ) ; } ) ; return $ result ; }

Lowercases any Roman numerals found in the string.

@param $s
@param string $matchMode
@return string

Lowercases any Roman numerals found in the string .


public function markdown($s, $flavor = 'gfm', $inlineOnly = false) : string
	{

		// If flavor is 'extra' we're looking for Parsedown

		if ($flavor == 'extra')
		{

			if ($inlineOnly) {
				return (new \ParsedownExtra())->line($s);
			} else {
				return (new \ParsedownExtra())->text($s);
			}

		}

		// Otherwise, use Craft's built-in Yii-powered parser

		$flavor = ($flavor == 'yii-extra' ? 'extra' : $flavor);

		if ($inlineOnly) {
			return Markdown::processParagraph($s, $flavor);
		} else {
			return Markdown::process($s, $flavor);
		}

	}

Parses text through Markdown.

@param $s
@param string $flavor
@param bool $inlineOnly
@return string


public function readTime($s, $rate = 200, $minimum = 1)
	{
		$words = $this->wordcount($s);
		return max( intval($minimum), floor($words / intval($rate)) );
	}

public function readTime ( $ s , $ rate = 200 , $ minimum = 1 ) { $ words = $ this -> wordcount ( $ s ) ; return max ( intval ( $ minimum ) , floor ( $ words / intval ( $ rate ) ) ) ; }

Calculates the units of time required for an average person to read the given passage of text.

// TODO: Add label and inflection

@param string $s
@param int $rate
@param int $minimum
@return mixed

Calculates the units of time required for an average person to read the given passage of text .


public function smartypants($s, $settings = []) : string
	{
		return Wordsmith::$plugin->typography->smartypants($s, $settings);
	}

public function smartypants ( $ s , $ settings = [ ] ) : string { return Wordsmith :: $ plugin -> typography -> smartypants ( $ s , $ settings ) ; }

c.f. PHP-Typography

@param string $s
@return string


public function substringAfterFirst($s, $separator)
	{
		$s = SubStringy::create($s)->substringAfterFirst($separator);
		return ($s === false ? null : $s);
	}

public function substringAfterFirst ( $ s , $ separator ) { $ s = SubStringy :: create ( $ s ) -> substringAfterFirst ( $ separator ) ; return ( $ s === false ? null : $ s ) ; }

Gets the substring after the first occurrence of a separator.
If no match is found returns an empty string.

(We're hijacking the return from SubStringy to return a `null` instead of boolean `false` if the substring isn't matched.)

c.f. SubStringy::substringAfterFirst()

@param string $s
@param string $separator

@return string|null

Gets the substring after the first occurrence of a separator . If no match is found returns an empty string .


public function substringAfterLast($s, $separator)
	{
		$s = SubStringy::create($s)->substringAfterLast($separator);
		return ($s === false ? null : $s);
	}

public function substringAfterLast ( $ s , $ separator ) { $ s = SubStringy :: create ( $ s ) -> substringAfterLast ( $ separator ) ; return ( $ s === false ? null : $ s ) ; }

Gets the substring after the last occurrence of a separator.
If no match is found returns an empty string.

(We're hijacking the return from SubStringy to return a `null` instead of boolean `false` if the substring isn't matched.)

c.f. SubStringy::substringAfterLast()

@param string $s
@param string $separator

@return Word

Gets the substring after the last occurrence of a separator . If no match is found returns an empty string .


public function substringBeforeFirst($s, $separator)
	{
		$s = SubStringy::create($s)->substringBeforeFirst($separator);
		return ($s === false ? null : $s);
	}

public function substringBeforeFirst ( $ s , $ separator ) { $ s = SubStringy :: create ( $ s ) -> substringBeforeFirst ( $ separator ) ; return ( $ s === false ? null : $ s ) ; }

Gets the substring before the first occurrence of a separator.
If no match is found returns an empty string.

(We're hijacking the return from SubStringy to return a `null` instead of boolean `false` if the substring isn't matched.)

c.f. SubStringy::substringBeforeFirst()

@param string $s
@param string $separator

@return Word

Gets the substring before the first occurrence of a separator . If no match is found returns an empty string .


public function substringBeforeLast($s, $separator)
	{
		$s = SubStringy::create($s)->substringBeforeLast($separator);
		return ($s === false ? null : $s);
	}

public function substringBeforeLast ( $ s , $ separator ) { $ s = SubStringy :: create ( $ s ) -> substringBeforeLast ( $ separator ) ; return ( $ s === false ? null : $ s ) ; }

Gets the substring before the last occurrence of a separator.
If no match is found returns an empty string.

(We're hijacking the return from SubStringy to return a `null` instead of boolean `false` if the substring isn't matched.)

c.f. SubStringy::substringBeforeLast()

@param string $s
@param string $separator

@return Word

Gets the substring before the last occurrence of a separator . If no match is found returns an empty string .


public function titleize($s, $ignore=[]) : string
	{
		return (string) Stringy::create($s)->titleize($ignore);
	}

public function titleize ( $ s , $ ignore = [ ] ) : string { return ( string ) Stringy :: create ( $ s ) -> titleize ( $ ignore ) ; }

Returns a trimmed string with the first letter of each word capitalized.

c.f. Stringy::titleize()

@param string $s
@param array $ignore
@return string

Returns a trimmed string with the first letter of each word capitalized .


public function trim($s, $chars = null) : string
	{
		return (string) Stringy::create($s)->trim($chars);
	}

public function trim ( $ s , $ chars = null ) : string { return ( string ) Stringy :: create ( $ s ) -> trim ( $ chars ) ; }

Returns a string with whitespace removed from the start and end of the string.

c.f. Stringy::trim()

@param string $s
@param string $chars
@return string

Returns a string with whitespace removed from the start and end of the string .


public function trimLeft($s, $chars = null) : string
	{
		return (string) Stringy::create($s)->trimLeft($chars);
	}

public function trimLeft ( $ s , $ chars = null ) : string { return ( string ) Stringy :: create ( $ s ) -> trimLeft ( $ chars ) ; }

Returns a string with whitespace removed from the start of the string.

c.f. Stringy::trimLeft()

@param string $s
@param string $chars
@return string

Returns a string with whitespace removed from the start of the string .


public function trimRight($s, $chars = null) : string
	{
		return (string) Stringy::create($s)->trimRight($chars);
	}

public function trimRight ( $ s , $ chars = null ) : string { return ( string ) Stringy :: create ( $ s ) -> trimRight ( $ chars ) ; }

Returns a string with whitespace removed from the end of the string.

c.f. Stringy::trimRight()

@param string $s
@param string $chars
@return string

Returns a string with whitespace removed from the end of the string .


public function typogrify($s, $settings = []) : string
	{
		return Wordsmith::$plugin->typography->typogrify($s, $settings);
	}

public function typogrify ( $ s , $ settings = [ ] ) : string { return Wordsmith :: $ plugin -> typography -> typogrify ( $ s , $ settings ) ; }

Typogrify applies a full suite of typographic treatments to beautify your web typography.

c.f. PHP-Typography

@param string $s
@return string

Typogrify applies a full suite of typographic treatments to beautify your web typography .


public function upperCaseRoman($s, $match_mode = 'strict') : string
	{
		$result = RomanNumerals::romanNumeralMatchCallback(
			$s,
			$match_mode,
			function (array $matches) {
				if (empty($matches[1])) {
					return $matches[1];
				}
				return strtoupper($matches[1]);
			}
		);
		return $result;
	}

public function upperCaseRoman ( $ s , $ match_mode = 'strict' ) : string { $ result = RomanNumerals :: romanNumeralMatchCallback ( $ s , $ match_mode , function ( array $ matches ) { if ( empty ( $ matches [ 1 ] ) ) { return $ matches [ 1 ] ; } return strtoupper ( $ matches [ 1 ] ) ; } ) ; return $ result ; }

Uppercases any Roman numerals found in the string.

@param $s
@param string $match_mode
@return string

Uppercases any Roman numerals found in the string .


public function widont($s, $settings = []) : string
	{
		return Wordsmith::$plugin->typography->widont($s, $settings);
	}

public function widont ( $ s , $ settings = [ ] ) : string { return Wordsmith :: $ plugin -> typography -> widont ( $ s , $ settings ) ; }

Replaces the space between the last two words in a string with a ` ` to prevent widowing.

c.f. PHP-Typography

@param string $s
@param array $settings
@return string

Replaces the space between the last two words in a string with a &nbsp ; to prevent widowing .


public static function getByName($settingName, $fallback = null)
    {
        if (static::$cachedRows === null) {
            static::cache();
        }

        if (! array_key_exists($settingName, static::$cachedRows)) {
            return $fallback;
        }

        return static::$cachedRows[$settingName];
    }

public static function getByName ( $ settingName , $ fallback = null ) { if ( static :: $ cachedRows === null ) { static :: cache ( ) ; } if ( ! array_key_exists ( $ settingName , static :: $ cachedRows ) ) { return $ fallback ; } return static :: $ cachedRows [ $ settingName ] ; }

Get the value settings by name.

@param  string $settingName Name of setting
@param  string $fallback Fallback if the setting does not exist
@return string


public function getIcon()
    {
        if (($icon = $this->getExtensionProperty('icon'))) {
            if ($file = array_get($icon, 'image')) {
                $file = $this->path.'/'.$file;

                if (file_exists($file)) {
                    $mimetype = pathinfo($file, PATHINFO_EXTENSION) === 'svg'
                        ? 'image/svg+xml'
                        : finfo_file(finfo_open(FILEINFO_MIME_TYPE), $file);
                    $data = file_get_contents($file);

                    $icon['backgroundImage'] = 'url(\'data:'.$mimetype.';base64,'.base64_encode($data).'\')';
                }
            }

            return $icon;
        }
    }

public function getIcon ( ) { if ( ( $ icon = $ this -> getExtensionProperty ( 'icon' ) ) ) { if ( $ file = array_get ( $ icon , 'image' ) ) { $ file = $ this -> path . '/' . $ file ; if ( file_exists ( $ file ) ) { $ mimetype = pathinfo ( $ file , PATHINFO_EXTENSION ) === 'svg' ? 'image/svg+xml' : finfo_file ( finfo_open ( FILEINFO_MIME_TYPE ) , $ file ) ; $ data = file_get_contents ( $ file ) ; $ icon [ 'backgroundImage' ] = 'url(\'data:' . $ mimetype . ';base64,' . base64_encode ( $ data ) . '\')' ; } } return $ icon ; } }

Loads the icon information from the composer.json.

@return array|null

Loads the icon information from the composer . json .


public function toArray()
    {
        return (array) array_merge($this->composerJson, [
            'id'            => $this->getId(),
            'name'          => $this->getName(),
            'version'       => $this->getVersion(),
            'path'          => $this->getPath(),
            'enabled'       => $this->isEnabled(),
            'icon'          => $this->getIcon(),
            'hasAssets'     => $this->hasAssets(),
            'hasMigrations' => $this->hasMigrations(),
        ]);
    }

public function toArray ( ) { return ( array ) array_merge ( $ this -> composerJson , [ 'id' => $ this -> getId ( ) , 'name' => $ this -> getName ( ) , 'version' => $ this -> getVersion ( ) , 'path' => $ this -> getPath ( ) , 'enabled' => $ this -> isEnabled ( ) , 'icon' => $ this -> getIcon ( ) , 'hasAssets' => $ this -> hasAssets ( ) , 'hasMigrations' => $ this -> hasMigrations ( ) , ] ) ; }

Generates an array result for the object.

@return array

Generates an array result for the object .


public function index(Request $request)
    {
        $tag = $request->get('tag');
        $data = $this->dispatch(new BlogIndexData($tag));
        $layout = $tag ? Tag::layout($tag)->first() : config('blog.tag_layout');
        $socialHeaderIconsUser = User::where('id', Settings::socialHeaderIconsUserId())->first();
        $css = Settings::customCSS();
        $js = Settings::customJS();

        return view($layout, $data, compact('css', 'js', 'socialHeaderIconsUser'));
    }

public function index ( Request $ request ) { $ tag = $ request -> get ( 'tag' ) ; $ data = $ this -> dispatch ( new BlogIndexData ( $ tag ) ) ; $ layout = $ tag ? Tag :: layout ( $ tag ) -> first ( ) : config ( 'blog.tag_layout' ) ; $ socialHeaderIconsUser = User :: where ( 'id' , Settings :: socialHeaderIconsUserId ( ) ) -> first ( ) ; $ css = Settings :: customCSS ( ) ; $ js = Settings :: customJS ( ) ; return view ( $ layout , $ data , compact ( 'css' , 'js' , 'socialHeaderIconsUser' ) ) ; }

Display the blog index page.

@param Request $request
@return \Illuminate\Http\Response


public function showPost($slug, Request $request)
    {
        $post = Post::with('tags')->whereSlug($slug)->firstOrFail();
        $socialHeaderIconsUser = User::where('id', Settings::socialHeaderIconsUserId())->first();
        $user = User::where('id', $post->user_id)->firstOrFail();
        $tag = $request->get('tag');
        $title = $post->title;
        $css = Settings::customCSS();
        $js = Settings::customJS();

        if ($tag) {
            $tag = Tag::whereTag($tag)->firstOrFail();
        }

        if (! $post->is_published && ! Auth::guard('canvas')->check()) {
            return redirect()->route('canvas.blog.post.index');
        }

        return view($post->layout, compact('post', 'tag', 'slug', 'title', 'user', 'css', 'js', 'socialHeaderIconsUser'));
    }

public function showPost ( $ slug , Request $ request ) { $ post = Post :: with ( 'tags' ) -> whereSlug ( $ slug ) -> firstOrFail ( ) ; $ socialHeaderIconsUser = User :: where ( 'id' , Settings :: socialHeaderIconsUserId ( ) ) -> first ( ) ; $ user = User :: where ( 'id' , $ post -> user_id ) -> firstOrFail ( ) ; $ tag = $ request -> get ( 'tag' ) ; $ title = $ post -> title ; $ css = Settings :: customCSS ( ) ; $ js = Settings :: customJS ( ) ; if ( $ tag ) { $ tag = Tag :: whereTag ( $ tag ) -> firstOrFail ( ) ; } if ( ! $ post -> is_published && ! Auth :: guard ( 'canvas' ) -> check ( ) ) { return redirect ( ) -> route ( 'canvas.blog.post.index' ) ; } return view ( $ post -> layout , compact ( 'post' , 'tag' , 'slug' , 'title' , 'user' , 'css' , 'js' , 'socialHeaderIconsUser' ) ) ; }

Display a blog post page.

@param $slug
@param Request $request
@return \Illuminate\Http\Response


public function store(TagCreateRequest $request)
    {
        $tag = new Tag();
        $tag->fill($request->toArray())->save();
        $tag->save();

        Session::put('_new-tag', trans('canvas::messages.create_success', ['entity' => 'tag']));

        return redirect()->route('canvas.admin.tag.index');
    }

public function store ( TagCreateRequest $ request ) { $ tag = new Tag ( ) ; $ tag -> fill ( $ request -> toArray ( ) ) -> save ( ) ; $ tag -> save ( ) ; Session :: put ( '_new-tag' , trans ( 'canvas::messages.create_success' , [ 'entity' => 'tag' ] ) ) ; return redirect ( ) -> route ( 'canvas.admin.tag.index' ) ; }

Store the newly created tag in the database.

@param TagCreateRequest $request

@return \Illuminate\Http\RedirectResponse

Store the newly created tag in the database .


public function edit($id)
    {
        $tag = Tag::findOrFail($id);
        $data = ['id' => $id];
        foreach (array_keys($this->fields) as $field) {
            $data[$field] = old($field, $tag->$field);
        }

        return view('canvas::backend.tag.edit', compact('data'));
    }

public function edit ( $ id ) { $ tag = Tag :: findOrFail ( $ id ) ; $ data = [ 'id' => $ id ] ; foreach ( array_keys ( $ this -> fields ) as $ field ) { $ data [ $ field ] = old ( $ field , $ tag -> $ field ) ; } return view ( 'canvas::backend.tag.edit' , compact ( 'data' ) ) ; }

Show the form for editing a tag.

@param  int $id

@return \Illuminate\View\View


public function update(TagUpdateRequest $request, $id)
    {
        $tag = Tag::findOrFail($id);
        $tag->fill($request->toArray())->save();
        $tag->save();

        Session::put('_update-tag', trans('canvas::messages.update_success', ['entity' => 'Tag']));

        return redirect()->route('canvas.admin.tag.edit', $id);
    }

public function update ( TagUpdateRequest $ request , $ id ) { $ tag = Tag :: findOrFail ( $ id ) ; $ tag -> fill ( $ request -> toArray ( ) ) -> save ( ) ; $ tag -> save ( ) ; Session :: put ( '_update-tag' , trans ( 'canvas::messages.update_success' , [ 'entity' => 'Tag' ] ) ) ; return redirect ( ) -> route ( 'canvas.admin.tag.edit' , $ id ) ; }

Update the tag in storage.

@param TagUpdateRequest $request
@param int $id

@return \Illuminate\Http\RedirectResponse


public function destroy($id)
    {
        $tag = Tag::findOrFail($id);
        $tag->delete();

        Session::put('_delete-tag', trans('canvas::messages.delete_success', ['entity' => 'Tag']));

        return redirect()->route('canvas.admin.tag.index');
    }

public function destroy ( $ id ) { $ tag = Tag :: findOrFail ( $ id ) ; $ tag -> delete ( ) ; Session :: put ( '_delete-tag' , trans ( 'canvas::messages.delete_success' , [ 'entity' => 'Tag' ] ) ) ; return redirect ( ) -> route ( 'canvas.admin.tag.index' ) ; }

Delete the tag.

@param  int $id

@return \Illuminate\Http\RedirectResponse


public function index()
    {
        $data = [
            'status' => App::isDownForMaintenance() ? CanvasHelper::MAINTENANCE_MODE_ENABLED : CanvasHelper::MAINTENANCE_MODE_DISABLED,
        ];

        return view('canvas::backend.tools.index', compact('data'));
    }

public function index ( ) { $ data = [ 'status' => App :: isDownForMaintenance ( ) ? CanvasHelper :: MAINTENANCE_MODE_ENABLED : CanvasHelper :: MAINTENANCE_MODE_DISABLED , ] ; return view ( 'canvas::backend.tools.index' , compact ( 'data' ) ) ; }

Display the tools page.

@return \Illuminate\View\View


public function clearCache()
    {
        $exitCode = Artisan::call('cache:clear');
        $exitCode = Artisan::call('route:clear');
        $exitCode = Artisan::call('optimize');
        if ($exitCode === 0) {
            Session::put('_cache-clear', trans('canvas::messages.cache_clear_success'));
        } else {
            Session::put('_cache-clear', trans('canvas::messages.cache_clear_error'));
        }

        return redirect()->route('canvas.admin.tools');
    }

public function clearCache ( ) { $ exitCode = Artisan :: call ( 'cache:clear' ) ; $ exitCode = Artisan :: call ( 'route:clear' ) ; $ exitCode = Artisan :: call ( 'optimize' ) ; if ( $ exitCode === 0 ) { Session :: put ( '_cache-clear' , trans ( 'canvas::messages.cache_clear_success' ) ) ; } else { Session :: put ( '_cache-clear' , trans ( 'canvas::messages.cache_clear_error' ) ) ; } return redirect ( ) -> route ( 'canvas.admin.tools' ) ; }

Manually Flush the Application Cache.

@return \Illuminate\View\View


public function handleDownload()
    {
        $this->storeUsers();
        $this->storePosts();
        $this->storeTags();
        $this->storePostTag();
        $this->storeMigrations();
        $this->storeUploads();
        $this->storePasswordResets();
        $this->storeSettings();
        $date = date('Y-m-d');
        $path = storage_path($date.'-canvas-archive');
        $filename = sprintf('%s.zip', $path);
        $zip = new \ZipArchive();
        $zip->open($filename, \ZipArchive::CREATE);
        $files = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator($path),
            \RecursiveIteratorIterator::LEAVES_ONLY
        );
        foreach ($files as $name => $file) {
            if (! $file->isDir()) {
                $filePath = $file->getRealPath();
                $relativePath = substr($filePath, strlen($path) + 1);
                $zip->addFile($filePath, $relativePath);
            }
        }
        $zip->close();
        \File::deleteDirectory(storage_path($date.'-canvas-archive'));

        return response()->download(storage_path($date.'-canvas-archive.zip'))->deleteFileAfterSend(true);
    }

public function handleDownload ( ) { $ this -> storeUsers ( ) ; $ this -> storePosts ( ) ; $ this -> storeTags ( ) ; $ this -> storePostTag ( ) ; $ this -> storeMigrations ( ) ; $ this -> storeUploads ( ) ; $ this -> storePasswordResets ( ) ; $ this -> storeSettings ( ) ; $ date = date ( 'Y-m-d' ) ; $ path = storage_path ( $ date . '-canvas-archive' ) ; $ filename = sprintf ( '%s.zip' , $ path ) ; $ zip = new \ ZipArchive ( ) ; $ zip -> open ( $ filename , \ ZipArchive :: CREATE ) ; $ files = new \ RecursiveIteratorIterator ( new \ RecursiveDirectoryIterator ( $ path ) , \ RecursiveIteratorIterator :: LEAVES_ONLY ) ; foreach ( $ files as $ name => $ file ) { if ( ! $ file -> isDir ( ) ) { $ filePath = $ file -> getRealPath ( ) ; $ relativePath = substr ( $ filePath , strlen ( $ path ) + 1 ) ; $ zip -> addFile ( $ filePath , $ relativePath ) ; } } $ zip -> close ( ) ; \ File :: deleteDirectory ( storage_path ( $ date . '-canvas-archive' ) ) ; return response ( ) -> download ( storage_path ( $ date . '-canvas-archive.zip' ) ) -> deleteFileAfterSend ( true ) ; }

Create and download an archive of all existing data.

@return \Illuminate\View\View

Create and download an archive of all existing data .


public function enableMaintenanceMode()
    {
        $exitCode = Artisan::call('down');
        if ($exitCode === 0) {
            Session::put('admin_ip', request()->ip());
            Session::put('_enable-maintenance-mode', trans('canvas::messages.enable_maintenance_mode_success'));
        } else {
            Session::put('_enable-maintenance-mode', trans('canvas::messages.enable_maintenance_mode_error'));
        }

        return redirect()->route('canvas.admin.tools');
    }

Enable Application Maintenance Mode.

@return \Illuminate\View\View


public function disableMaintenanceMode()
    {
        $exitCode = Artisan::call('up');
        if ($exitCode === 0) {
            Session::put('_disable-maintenance-mode', trans('canvas::messages.disable_maintenance_mode_success'));
        } else {
            Session::put('_disable-maintenance-mode', trans('canvas::messages.disable_maintenance_mode_error'));
        }

        return redirect()->route('canvas.admin.tools');
    }

Disable Application Maintenance Mode.

@return \Illuminate\View\View


private function handleConfigs()
    {
        $configPath = __DIR__.'/../config/blog.php';

        // Allow publishing the config file, with tag: config
        $this->publishes([$configPath => config_path('blog.php')], 'config');

        // Merge config files...
        // Allows any modifications from the published config file to be seamlessly merged with default config file
        $this->mergeConfigFrom($configPath, 'blog');
    }


private function handleTranslations()
    {
        // Set locale for Carbon
        Carbon::setLocale(config('app.locale'));

        // Load translations...
        $this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'canvas');

        // Allow publishing translation files, with tag: translations
        $this->publishes([
            __DIR__.'/../resources/lang' => base_path('resources/lang/vendor/canvas'),
        ], 'translations');
    }


private function handleViews()
    {
        // Load the views...
        $this->loadViewsFrom(__DIR__.'/../resources/views', 'canvas');

        // Allow publishing view files, with tag: views
        $this->publishes([
            __DIR__.'/../resources/views/auth' => base_path('resources/views/vendor/canvas/auth'),
            __DIR__.'/../resources/views/backend' => base_path('resources/views/vendor/canvas/backend'),
            __DIR__.'/../resources/views/errors' => base_path('resources/views/vendor/canvas/errors'),
            __DIR__.'/../resources/views/frontend' => base_path('resources/views/vendor/canvas/frontend'),
        ], 'views');
    }


public function index()
    {
        $userData = Auth::guard('canvas')->user()->toArray();
        $blogData = config('blog');
        $data = array_merge($userData, $blogData);

        return view('canvas::backend.profile.index', compact('data'));
    }

public function index ( ) { $ userData = Auth :: guard ( 'canvas' ) -> user ( ) -> toArray ( ) ; $ blogData = config ( 'blog' ) ; $ data = array_merge ( $ userData , $ blogData ) ; return view ( 'canvas::backend.profile.index' , compact ( 'data' ) ) ; }

Display the user profile page.

@return \Illuminate\View\View