/** * Construct Validation rule * * @param array $attribute * @param array $options */ public function __construct($attribute, $options) { // verify options $valid = array('on' => 'save', 'allowNull' => false, 'onlyInteger' => true, 'message' => Mad_Model_Errors::$defaultErrorMessages['notNumber']); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); $this->_attribute = $attribute; }
/** * Construct Validation rule * * @param array $attribute * @param array $options */ public function __construct($attribute, $options) { // verify options $valid = array('on' => 'save', 'message' => Mad_Model_Errors::$defaultErrorMessages['empty']); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); $this->_attribute = $attribute; }
/** * Construct Validation rule * * @param array $attribute * @param array $options */ public function __construct($attribute, $options) { // verify options $valid = array('on' => 'save', 'allowNull', 'minimum', 'maximum', 'is', 'within', 'tooLong' => Mad_Model_Errors::$defaultErrorMessages['tooLong'], 'tooShort' => Mad_Model_Errors::$defaultErrorMessages['tooShort'], 'wrongLength' => Mad_Model_Errors::$defaultErrorMessages['wrongLength']); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); $this->_attribute = $attribute; }
/** * Construct Validation rule * * @param array $attribute * @param array $options */ public function __construct($attribute, $options) { $this->_attribute = $attribute; $valid = array('in', 'on' => 'save', 'allowNull' => false, 'strict' => false, 'message' => Mad_Model_Errors::$defaultErrorMessages['inclusion']); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); if (!is_array($this->_options['in']) && !$this->_options['in'] instanceof Traversable) { throw new InvalidArgumentException("'in' must be an array or traversable"); } }
/** * Construct Validation rule * * @param array $attribute * @param array $options */ public function __construct($attribute, $options) { $this->_attribute = $attribute; // verify options $valid = array('on' => 'save', 'with', 'message' => Mad_Model_Errors::$defaultErrorMessages['invalid']); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); // validate regular expression if (@preg_match($this->_options['with'], '') === false) { $msg = "Bad regular expression '{$this->_options['with']}'"; throw new UnexpectedValueException($msg); } }
/** * Construct association object * * @param string $assocName * @param array $options * @param object $model */ public function __construct($assocName, $options, Mad_Model_Base $model) { $valid = array('className', 'foreignKey', 'primaryKey', 'include', 'order', 'dependent' => 'nullify'); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); $this->_assocName = $assocName; $this->_model = $model; $this->_conn = $model->connection(); // get inflections $toMethod = Mad_Support_Inflector::camelize($this->_assocName, 'lower'); $toMethod = str_replace('/', '_', $toMethod); $toClass = ucfirst($toMethod); $this->_methods = array($toMethod => 'getObject', $toMethod . '=' => 'setObject', 'build' . $toClass => 'buildObject', 'create' . $toClass => 'createObject'); }
/** * Construct association object * * @param string $assocName * @param array $options * @param object $model */ public function __construct($assocName, $options, Mad_Model_Base $model) { $valid = array('className', 'conditions', 'order', 'foreignKey', 'primaryKey', 'associationForeignKey', 'associationPrimaryKey', 'joinTable', 'uniq', 'include', 'finderSql', 'deleteSql', 'insertSql'); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); $this->_assocName = $assocName; $this->_model = $model; $this->_conn = $model->connection(); // get inflections $toMethod = Mad_Support_Inflector::camelize($this->_assocName, 'lower'); $toMethod = str_replace('/', '_', $toMethod); $singular = Mad_Support_Inflector::singularize($toMethod); $toClass = ucfirst($singular); $this->_methods = array($toMethod => 'getObjects', $toMethod . '=' => 'setObjects', $singular . 'Ids' => 'getObjectIds', $singular . 'Ids=' => 'setObjectIds', $singular . 'Count' => 'getObjectCount', 'add' . $toClass => 'addObject', Mad_Support_Inflector::pluralize('replace' . $toClass) => 'replaceObjects', Mad_Support_Inflector::pluralize('delete' . $toClass) => 'deleteObjects', Mad_Support_Inflector::pluralize('clear' . $toClass) => 'clearObjects', Mad_Support_Inflector::pluralize('find' . $toClass) => 'findObjects'); }
/** * Construct association object * * @param string $assocName * @param array $options */ public function __construct($assocName, $options, Mad_Model_Base $model) { $valid = array('className', 'foreignKey', 'associationForeignKey', 'primaryKey', 'associationPrimaryKey', 'include', 'select', 'conditions', 'order', 'finderSql', 'through', 'dependent' => 'nullify'); $this->_options = Mad_Support_Base::assertValidKeys($options, $valid); $this->_assocName = $assocName; $this->_model = $model; $this->_conn = $model->connection(); // throw fatal error if through option is invalid $this->_throughClass = Mad_Support_Inflector::classify($this->_options['through']); class_exists($this->_throughClass); // get inflections $toMethod = Mad_Support_Inflector::camelize($this->_assocName, 'lower'); $toMethod = str_replace('/', '_', $toMethod); $singular = Mad_Support_Inflector::singularize($toMethod); $toClass = ucfirst($singular); $this->_methods = array($toMethod => 'getObjects', $singular . 'Ids' => 'getObjectIds', $singular . 'Count' => 'getObjectCount', 'add' . $toClass => 'addObject', Mad_Support_Inflector::pluralize('delete' . $toClass) => 'deleteObjects', Mad_Support_Inflector::pluralize('clear' . $toClass) => 'clearObjects', Mad_Support_Inflector::pluralize('find' . $toClass) => 'findObjects'); }
/** * Renders Digg-style pagination. (We know you wanna!) * Returns '1' if there is only one page in total (can't paginate that). */ public function willPaginate($entries, $options = array()) { $totalPages = $entries->pageCount; if ($totalPages < 1) { return; } $page = $entries->currentPage; // get options $valids = array('href', 'class' => 'pagination', 'prevLabel' => "← Prev", 'nextLabel' => 'Next →', 'innerWindow' => 2, 'outerWindow' => 1); $options = Mad_Support_Base::assertValidKeys($options, $valids); $href = $options['href']; unset($options['href']); $innerWindow = $options['innerWindow']; unset($options['innerWindow']); $outerWindow = $options['outerWindow']; unset($options['outerWindow']); $prevLabel = $options['prevLabel']; unset($options['prevLabel']); $nextLabel = $options['nextLabel']; unset($options['nextLabel']); $min = $page - $innerWindow; $max = $page + $innerWindow; $current = range($min, $max); $beginning = range(1, 1 + $outerWindow); $tail = range($totalPages - $outerWindow, $totalPages); $visible = array_merge($current, $beginning, $tail); $links = array(); foreach (range(1, $totalPages) as $n) { if (in_array($n, $visible)) { $links[] = $this->_linkOrSpan($n, $n == $page, 'current', $n, $href); } elseif ($n == $beginning[sizeof($beginning) - 1] + 1 || $n == $tail[0] - 1) { $links[] = '... '; } } if (($prev = $page - 1) > 0) { $prevLink = $this->_linkOrSpan($prev, $prev == 0, 'disabled', $prevLabel, $href); array_unshift($links, $prevLink); } if (($succ = $page + 1) <= $totalPages) { $nextLink = $this->_linkOrSpan($succ, $succ > $totalPages, 'disabled', $nextLabel, $href); array_push($links, $nextLink); } return $this->contentTag('div', join('', $links), $options); }
/** * @param array $options */ public function attachment($options = array()) { $valid = array('filename' => 'attachment', 'body' => '', 'contentType' => 'application/octet-stream', 'transferEncoding' => 'base64'); $options = Mad_Support_Base::assertValidKeys($options, $valid); // verify body & filename if (empty($options['body'])) { $msg = "Content for attachment " . $options['filename'] . " is empty"; throw new Mad_Mailer_Exception($msg); } if (empty($options['filename'])) { $msg = "Filename for attachment " . $options['filename'] . " is empty"; throw new Mad_Mailer_Exception($msg); } // generate unique filename $filename = $options['filename']; if (!empty($this->_attachments[$filename])) { $i = 0; $base = substr($filename, 0, strrpos($filename, '.')); $ext = substr($filename, strrpos($filename, '.')); // increment to my_image_1, my_image_2, etc do { $i++; $filename = $base . '-' . $i . $ext; } while (!empty($this->_attachments[$filename])); $options['filename'] = $filename; } // add to list of attachments $this->_attachments[$filename] = $options; }
/** * Construct the sql used to do a find() method * * @param array $options * @return string the SQL */ protected function _constructFinderSql($options) { $valid = array('select', 'from', 'conditions', 'include', 'order', 'group', 'limit', 'offset'); $options = Mad_Support_Base::assertValidKeys($options, $valid); $sql = "SELECT " . ($options['select'] ? $options['select'] : $this->getColumnStr()); $sql .= " FROM " . ($options['from'] ? $options['from'] : $this->tableName()); $sql = $this->_addConditions($sql, $options['conditions']); if ($options['group']) { $sql .= ' GROUP BY ' . $options['group']; } if ($options['order']) { $sql .= ' ORDER BY ' . $options['order']; } return $this->connection->addLimitOffset($sql, $options); }
/** * @return array */ public function findObjectsUsingJoin($type, $options, $binds) { $valid = array('conditions', 'include', 'order', 'limit', 'offset', 'page', 'perPage'); $options = Mad_Support_Base::assertValidKeys($options, $valid); // tables/keys/values $assocTable = $this->getAssocTable(); $joinTable = $this->getJoinTable(); $fkName = $this->getFkName(); $assocFkName = $this->getAssocFkName(); $assocPkName = $this->getAssocPkName(); $assocCols = $this->getAssocModel()->getColumnStr($assocTable); $pkValue = $this->getPkValue(); // build find options $conditions = $this->_constructConditions($options['conditions']); $order = $this->_constructOrder($options['order']); $include = $this->_constructInclude($options['include']); // build find options $options = array('select' => $assocCols, 'from' => "{$assocTable}, {$joinTable}", 'conditions' => "{$assocTable}.{$assocPkName} = {$joinTable}.{$assocFkName} " . "AND {$joinTable}.{$fkName} = :pkValue {$conditions}", 'order' => $options['order'], 'limit' => $options['limit'], 'offset' => $options['offset'], 'page' => $options['page'], 'perPage' => $options['perPage']); $binds[':pkValue'] = $pkValue; if (!empty($options['page'])) { return $this->getAssocModel()->paginate($options, $binds); } else { unset($options['page']); unset($options['perPage']); return $this->getAssocModel()->find($type, $options, $binds); } }
public function dropReceivingElement($elementId, $options = array()) { $js = Mad_Support_Base::chopToNull($this->dropReceivingElementJs($elementId, $options)); return $this->javascriptTag($js); }
public function testChopToNull() { $actual = Mad_Support_Base::chopToNull(''); $expected = null; $this->assertSame($expected, $actual); $actual = Mad_Support_Base::chopToNull('x'); $expected = null; $this->assertSame($expected, $actual); }
/** * Assert that the controller action sent a file. There are a few options you * can also assert * * {{code: php * ... * // assert that a document with the filname test.pdf was sent * $this->assertFileSent(array('filename' => 'test.pdf')); * * // assert that a document was setn as application/octet-stream type * $this->assertFileSent(array('type' => 'application/octet-stream')); * * // assert that a document was sent as an attachment * $this->assertFileSent(array('disposition' => 'attachment')); * ... * }} * * @param array $options * @param string $msg */ public function assertFileSent($options = array(), $msg = null) { $valid = array('filename', 'type', 'disposition'); $options = Mad_Support_Base::assertValidKeys($options, $valid); // parse headers for info in the format of: // 'Content-Type: application/octet-stream' // 'Content-Disposition: attachment; filename=test.jpg' foreach ($this->response->getHeaders() as $header => $value) { // parse out type if (strstr($header, 'Content-Type')) { preg_match('/Type: (.*)/', $header, $matches); $type = $matches[1]; } // parse out disposition/filename if (strstr($header, 'Content-Disposition')) { preg_match('/Disposition: (.*); filename=(.*)/', $header, $matches); $disposition = $matches[1]; $filename = $matches[2]; } } // make sure file was sent $msg = "File was not sent in this request"; $this->assertTrue(!empty($disposition) && !empty($filename) && !empty($type), $msg); // assert type if (!empty($options['type'])) { $this->assertEquals($options['type'], $type, 'Content-Type does not match expected'); } // assert disposition if (!empty($options['disposition'])) { $this->assertEquals($options['disposition'], $disposition, 'Content-Disposition does not match expected'); } // assert filename if (!empty($options['filename'])) { $this->assertEquals($options['filename'], $filename, 'filename does not match expected'); } }
/** * Find an associated object according to the same runs as Mad_Model_Base * * @param array $args * @return array */ public function findObjects($args = array()) { // method arguments - validate $type = isset($args[0]) ? $args[0] : 'all'; $options = isset($args[1]) ? $args[1] : array(); $binds = isset($args[2]) ? $args[2] : array(); $valid = array('select', 'conditions', 'include', 'order', 'limit', 'offset', 'page', 'perPage'); $options = Mad_Support_Base::assertValidKeys($options, $valid); // keys/values $assoc = $this->_conn->quoteColumnName($this->getAssocTable()); $fkName = $this->_conn->quoteColumnName($this->getFkName()); $pkValue = $this->getPkValue(); // build find options $conditions = "{$assoc}.{$fkName} = :pkValue " . $this->_constructConditions($options['conditions']); $order = $this->_constructOrder($options['order']); $select = $this->_constructSelect($options['select']); $include = $this->_constructInclude($options['include']); $options = array('conditions' => $conditions, 'order' => $order, 'select' => $select, 'include' => $include, 'order' => $options['order'], 'limit' => $options['limit'], 'offset' => $options['offset'], 'page' => $options['page'], 'perPage' => $options['perPage']); $binds[':pkValue'] = $pkValue; // Query for the associated objects if (!empty($options['page'])) { return $this->getAssocModel()->paginate($options, $binds); } else { unset($options['page']); unset($options['perPage']); return $this->getAssocModel()->find($type, $options, $binds); } }
/** * Parse the fixture data from the given array. This will * take the yaml file and validate and set the records/options. */ private function _parseYml($ymlName, $fixturesPath) { // only parse if not in cache if (!isset(self::$_ymlCache[$ymlName])) { $fixtureFile = "{$fixturesPath}/{$ymlName}.yml"; // Parse yml file if (!file_exists($fixtureFile)) { throw new Mad_Test_Exception('The fixture file: "' . $fixtureFile . '" does not exist.'); } // dynamic fixtures ob_start(); include "madview://{$fixtureFile}"; $fixtureData = ob_get_clean(); $records = Horde_Yaml::load($fixtureData); // Parse options $options = isset($records['options']) ? $records['options'] : array(); $valid = array('table' => $ymlName, 'log' => null, 'requires' => array(), 'before' => array(), 'after' => array(), 'teardown' => array()); $options = Mad_Support_Base::assertValidKeys($options, $valid); unset($records['options']); self::$_ymlCache[$ymlName] = array('records' => $records, 'options' => $options); } $this->_records = self::$_ymlCache[$ymlName]['records']; $this->_options = self::$_ymlCache[$ymlName]['options']; // Parse required fixtures for this load foreach ($this->_options['requires'] as $required) { $this->_required[] = new Mad_Test_Fixture_Base($this->_connection, $required); } }
<?php // env define('MAD_ROOT', dirname(dirname(__FILE__))); if (!defined('MAD_ENV')) { define('MAD_ENV', isset($_SERVER['MAD_ENV']) ? $_SERVER['MAD_ENV'] : 'development'); } ini_set('date.timezone', 'US/Pacific'); // include paths set_include_path(implode(PATH_SEPARATOR, array(MAD_ROOT . '/app', MAD_ROOT . '/app/controllers', MAD_ROOT . '/app/helpers', MAD_ROOT . '/app/models', MAD_ROOT . '/config', MAD_ROOT . '/lib', MAD_ROOT . '/test', MAD_ROOT . '/vendor', get_include_path()))); // initialization required by framework require_once 'Mad/Support/Base.php'; Mad_Support_Base::initialize(); // error reporting if (MAD_ENV == 'production') { error_reporting(0); } else { ini_set('display_errors', 1); error_reporting(E_ALL | E_STRICT); } // initialize the default loger. writers and filters are specified in the environment files. $GLOBALS['MAD_DEFAULT_LOGGER'] = new Horde_Log_Logger(); $writer = new Horde_Log_Handler_Stream(MAD_ROOT . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . MAD_ENV . '.log'); $GLOBALS['MAD_DEFAULT_LOGGER']->addHandler($writer); // priority filters if (MAD_ENV == 'development') { $filter = new Horde_Log_Filter_Level(Horde_Log::INFO); $GLOBALS['MAD_DEFAULT_LOGGER']->addFilter($filter); } elseif (MAD_ENV == 'production') { $filter = new Horde_Log_Filter_Level(Horde_Log::NOTICE); $GLOBALS['MAD_DEFAULT_LOGGER']->addFilter($filter);
/** * Load fixture(s) data into the database. * * <code> * <?php * ... * // single * $this->fixtures('briefcases'); * * // multiple * $this->fixtures(array('briefcases', 'md_metadata')); * * // 'only' for given test methods * $this->fixtures('briefcases', array('only' => array('testMethod1', 'testMethod2'))); * * // all test methods 'except' given * $this->fixtures('briefcases', array('except' => array('testMethod1', 'testMethod2'))); * ... * ?> * </code> * * @param string|array $ymlFiles * @param array $options */ public function fixtures($args) { $ymlFiles = func_get_args(); $last = end($ymlFiles); $options = is_array($last) ? array_pop($ymlFiles) : array(); // don't load fixtures for these methods if (isset($options['except'])) { if (in_array($this->getName(), $options['except'])) { return; } } // only load fixtures for these methods if (isset($options['only'])) { if (!in_array($this->getName(), $options['only'])) { return; } } // Add fixtures to the existing fixtures when called more than once if (empty($this->_fixtures)) { $this->_fixtures = new Mad_Test_Fixture_Collection($this->_conn, $ymlFiles); } else { $this->_fixtures->addFixture($ymlFiles); } // Build models from fixture records foreach ($this->_fixtures->getFixtures() as $fixture) { $name = $fixture->getYmlName(); if (isset($this->_fixtureClassNames[$name])) { $class = $this->_fixtureClassNames[$name]; } else { $table = $fixture->getTableName(); $class = Mad_Support_Inflector::classify($table); } // skip building model if class doesn't exist if (!Mad_Support_Base::modelExists($class)) { break; } $model = new $class(); $this->_records[$name] = array(); foreach ($fixture->getRecords() as $recordName => $attrs) { $this->_records[$name][$recordName] = $model->instantiate($attrs); } } // @deprecated - assign public properties based on fixture names foreach ($this->_fixtures->getRecords() as $recordName => $values) { if (isset($this->{$recordName})) { $this->{$recordName} = array_merge($this->{$recordName}, $values); } else { $this->{$recordName} = $values; } // make all values strings foreach ($this->{$recordName} as &$value) { $value = (string) $value; } } }
/** * Render a partial template. Partial template filenames are named with * a leading underscore, although this underscore is not used when * specifying the name of the partial. * * we would reference the file /views/shared/_sidebarInfo.html * in our template using: * * <code> * <div> * <?= $this->renderPartial('sidebarInfo'); ?> * </div> * </code> * * @param string $name * @param array $options * @return string The template output */ public function renderPartial($name, $options = array()) { // pop name off of the path $parts = strstr($name, '/') ? explode('/', $name) : array($name); $name = array_pop($parts); $path = implode('/', $parts) . "/"; // check if they passed in a collection before validating keys $useCollection = array_key_exists('collection', $options); $valid = array('object', 'locals' => array(), 'collection' => array()); $options = Mad_Support_Base::assertValidKeys($options, $valid); $locals = array($name => null); // set the object variable if ($options['object']) { $locals[$name] = $options['object']; } // set local variables to be used in the partial foreach ($options['locals'] as $key => $val) { $locals[$key] = $val; } // collection if ($useCollection) { $rendered = ''; if ($options['collection'] instanceof Mad_Model_Collection || $options['collection'] instanceof Mad_Model_PaginatedCollection || is_array($options['collection'])) { $sz = count($options['collection']); for ($i = 0; $i < $sz; $i++) { $locals["{$name}Counter"] = $i; $locals[$name] = $options['collection'][$i]; $rendered .= $this->render("{$path}_{$name}", $locals); } } // single render } else { $rendered = $this->render("{$path}_{$name}", $locals); } return $rendered; }
/** * Remove either an except/only filter * @param string $type * @param string $method * @param array $options */ private function _removeFilter($type, $method, $options) { // validate options $valid = array('except', 'only'); $options = Mad_Support_Base::assertValidKeys($options, $valid); $thisAction = $this->params[':controller'] . '::' . $this->params[':action']; // only skip filter for specified controller::actions if ($options['only']) { $only = $this->_parseFilterController($options['only']); if (in_array($thisAction, $only)) { unset($this->_filters[$type][$method]); } // skip filter for all but the specified controller::actions } elseif ($options['except']) { $except = $this->_parseFilterController($options['except']); if (!in_array($thisAction, $except)) { unset($this->_filters[$type][$method]); } // skip for all methods in this controller } else { unset($this->_filters[$type][$method]); } }