/** * This is a simple system to generate unique keys. It will need to be improved in the future for better performance. * * @param Object $object - must have a getPeer method. */ private static function getUniqueKey($object, $ppk_field = self::KEY_FIELD_NAME, $key_length = self::KEY_LENGTH, $key_char_pool = self::KEY_CHARACTER_POOL) { $object_peer = self::getObjectPeer($object); if (is_null($object_peer)) { throw new \Exception("Object must have a Peer class."); } $tries = 0; while (self::primaryKeyValueExists($new_id = \Altumo\String\String::generateRandomString($key_length, $key_char_pool), $object_peer, $ppk_field)) { if ($tries++ > 30) { throw new \Exception("Tried to generate a unique value for {$ppk_field} {$tries} times and failed."); } } return $new_id; }
/** * Constructor for this ApiFieldMap. * * @param string $request_field * @param integer $flags //a combination of flags of this field * @param string $description * @param string $model_accessor * //eg. provide: "CountryByCountryCode" and it will become * "getCountryByCountryCode" and "setCountryByCountryCode" * * @return \sfAltumoPlugin\Api\ApiFieldMap */ public function __construct($request_field, $flags = null, $description = null, $model_accessor = null) { if (!is_string($request_field)) { throw new \Exception('Request field must be a string.'); } $this->setRequestField($request_field); if (!is_null($flags)) { $this->setFlags($flags); } if (!is_null($description)) { $this->setDescription($description); } else { $description = \Altumo\String\String::formatTitleCase(str_replace('_', ' ', $request_field)); $this->setDescription($description); } if (!is_null($model_accessor)) { $this->setModelAccessor($model_accessor); } else { $accessor_suffix = \Altumo\String\String::formatCamelCase($request_field); $this->setModelAccessor($accessor_suffix); } }
/** * Formats a JSON string into a pretty JSON string. * * @todo Fix so text-qualified characters eg. ",{[" don't break formatting. * * @param string $json * @return string */ public static function format($json) { $indent_character = ' '; $indent_count = 0; $json_length = strlen($json); $position = 0; $insert_newline_after = function ($offset) use(&$json, &$indent_character, &$indent_count, &$position) { $indent = str_repeat($indent_character, $indent_count); $json = \Altumo\String\String::insert("\n" . $indent, $json, $offset + 1); $position += strlen($indent) + 1; }; for (; $position < $json_length; $position++) { $character = $json[$position]; switch ($character) { case ':': //insert a space after colons $json = \Altumo\String\String::insert(" ", $json, $position + 1); $position++; break; case ',': $insert_newline_after($position); break; case '[': case '{': $indent_count++; $insert_newline_after($position); break; case ']': case '}': $indent_count--; $insert_newline_after($position - 1); break; default: } $json_length = strlen($json); } return $json; }
/** * Returns this full URL as a string. * * * @throws \Exception //if this URL is not valid * * @return string */ public function getUrl() { $url_string = $this->getScheme(); $url_string .= '://'; if ($this->hasLogin()) { $url_string .= $this->getLogin() . '@'; } $url_string .= $this->getHostPort(); $url_string .= $this->getPath(); if ($this->hasParameters()) { $url_string .= \Altumo\String\String::generateUrlParameterString($this->getParameters()); } if ($this->hasAnchor()) { $url_string .= '#' . urlencode($this->getAnchor()); } $this->setFullUrl($url_string); if (!$this->isValid()) { throw new \Exception('This URL is invalid.'); } return $url_string; }
/** * Stores the SSL certificate in a temporary file and returns its path. * * When making a request with an SSL certificate, curl requires that * certificate to be in a file. This function stores the certificate in a * temporary file and returns its path. * * * @see deleteSslCertificateTempFile * // This method will be called after the certificate has been used in order * // to clean up the file that was created. * * @throws \Exception * // If the temp certificate file cannot be created or written * * @param string $temp_path */ protected function createSslCertificateTempFile() { // If a certificate temp file has already been created, delete it $this->deleteSslCertificateTempFile(); // Gets certificate data $ssl_cert_data = $this->getSslCertificateData(); \Altumo\Validation\Strings::assertNonEmptyString($ssl_cert_data); // Use system temp directory path $temp_path = sys_get_temp_dir(); // Make a new filename for the certificate using its own hash and a random string $temp_filename = $temp_path . '/altumo_pem_' . sha1($ssl_cert_data) . '_' . \Altumo\String\String::generateRandomString(4); // Write the contents of the certificate to the temporary file if (file_put_contents($temp_filename, $this->getSslCertificateData()) === false) { throw new \Exception('Unable to write to temporary certificate file.'); } $this->setSslCertificateTempFile($temp_filename); return $temp_filename; }
/** * Constructor for this ApiWriteOperation. * * * @param \sfAltumoPlugin\Api\ApiRequest $request * * @param \sfAltumoPlugin\Api\ApiResponse $response * * @param string $body_name * //the plural name of the container of the results. * eg. system_events * * @param function $modify_result( &$model, &$result ) * //Used in both Automatic and Manual Modes. The function that turns the * array of model objects into an array of \stdClass objects (the final * result). Must return an array of \stdClass objects. * In Manual mode, $result is an empty \stdClass that you modify. * Because $result is required to be passed by reference, any * modifications to $result will be the result that is returned from the * API. Also, the $model is a \stdClass (or can be). * In Automatic mode, $result will have to be constructed with * the modify_result callback. You should be able to share the * modify_result callback with GET, POST and PUT. Also, in auto, the * $model object is guaranteed to be a model object. * * @param function $before_save( &$model, &$request_object, &$response, * $remote_id ) * //Used in Automatic Mode. The function to call that is invoked just * just before the model is saved (after all of the accessor have been * called). You can attached an Error to the response with this remote_id * to prevent this model from being saved and output an appropriate error * message. * * @param \ModelCriteria $query * //The model Query that is used to look up an existing record for * PUT operations. If null, it will just use the default one from the * model. * * @param string $model_name * //Used in Automatic Mode. The model's class name. If null, it tries to * guess based off of the $body_name. * eg. * system_events * becomes * SystemEvent * * @param array $field_maps * //Used in Automatic Mode. An array of ApiFieldMap objects that describes * each of the fields' relationship with a the $model_name model. * Defaults to a required field. If null, description and setter_method * are generated according to the naming convention, unless overridden. * eg. * //legend: [ field_key, required, description, setter_method ] * $field_maps = array( * new \sfAltumoPlugin\Api\ApiFieldMap( 'system_event' ), * new \sfAltumoPlugin\Api\ApiFieldMap( 'remote_url', true, * 'Remote URL' ), * new \sfAltumoPlugin\Api\ApiFieldMap( 'enabled', false, null, * 'Enabled' ) //will become setEnabled and getEnabled * ); * * @param boolean * //Determines if this ApiWriteOperation is a POST (create) or a PUT * (update). If true, this is a PUT. Default false (POST). * * @param integer $mode * //Whether this is \sfAltumoPlugin\Api\ApiWriteOperation::MODE_AUTOMATIC * or \sfAltumoPlugin\Api\ApiWriteOperation::MODE_AUTOMATIC. Defaults to * automatic. * * @param function $process_objects_manually( &$response, &$objects ){ * //Used in Manual Mode. The function to call in order to perform a manual * write operation. Must return an array of saved Models or stdObjects. * $objects is an array of stdObjects that is the request body. * * @param function $before_setters( &$model, &$request_object, &$response ) * //Used in Automatic Mode. The function to call that is invoked just * after the model is created (before all of the accessor have been * called). This will only be invoked if this is a create (POST). * * @param function $after_save( $new_model, $request_object, $response, $remote_id, $update ) * //Used in Automatic Mode. The function to call that is invoked just after the model is saved. * Any exception thrown will cause the entire operation to be rolled-back. * * @throws \Exception * //if $field_maps is not an array * * @return \sfAltumoPlugin\Api\ApiWriteOperation */ public function __construct($request, $response, $body_name, $field_maps = array(), $update = false, $modify_result = null, $before_save = null, $query = null, $model_name = null, $mode = self::MODE_AUTOMATIC, $process_objects_manually = null, $before_setters = null, $after_save = null) { //request $this->setRequest($request); //response and body name $response_body = new \sfAltumoPlugin\Api\ApiResponseBody(array(), $body_name); $response->setResponseBody($response_body); $this->setResponse($response); //field maps if (!is_array($field_maps)) { throw new \Exception('Field maps must be an array of ApiFieldMap objects.'); } $this->setFieldMaps($field_maps); //update $this->setUpdate($update); //modify result callback if (is_callable($modify_result)) { $this->setModifyResult($modify_result); } //before save if (is_callable($before_save)) { $this->setBeforeSave($before_save); } // after save if (is_callable($after_save)) { $this->setAfterSave($after_save); } //query $this->setQuery($query); //model name if (is_null($model_name)) { $plural_model = \Altumo\String\String::formatCamelCase($body_name); $this->setModelName(substr($plural_model, 0, strlen($plural_model) - 1)); } else { $this->setModelName($model_name); } //mode $this->setMode($mode); //manually process objects if (is_callable($process_objects_manually)) { $this->setProcessObjectsManually($process_objects_manually); } //before save if (is_callable($before_setters)) { $this->setBeforeSetters($before_setters); } }
/** * Tests String::getTruncatedText() * */ public function testGetTruncatedText() { $input = 'know thyself'; $output = \Altumo\String\String::getTruncatedText($input, 10); $this->assertTrue($output === 'know...'); }