function beforeRender() { $models = ClassRegistry::keys(); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } }
public function render($view = null, $layout = null) { $event = new CakeEvent('Controller.beforeRender', $this); $this->getEventManager()->dispatch($event); if ($event->isStopped()) { $this->autoRender = false; return $this->response; } if (!empty($this->uses) && is_array($this->uses)) { foreach ($this->uses as $model) { list($plugin, $className) = pluginSplit($model); $this->request->params['models'][$className] = compact('plugin', 'className'); } } $viewClass = $this->viewClass; if ($this->viewClass != 'View') { list($plugin, $viewClass) = pluginSplit($viewClass, true); $viewClass = $viewClass . 'View'; App::uses($viewClass, $plugin . 'View'); } else { // ELSE IS CUSTOM In ORDER To Provide the right layout even were we are ( as plugin ... ) list($plugin, $viewClass) = pluginSplit($viewClass, true); $viewClass = 'Trois' . 'View'; App::uses($viewClass, 'Trois.' . 'View'); } $View = new $viewClass($this); $models = ClassRegistry::keys(); foreach ($models as $currentModel) { $currentObject = ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model')) { $className = get_class($currentObject); list($plugin) = pluginSplit(App::location($className)); $this->request->params['models'][$currentObject->alias] = compact('plugin', 'className'); $View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors; } } $this->autoRender = false; $this->View = $View; $this->response->body($View->render($view, $layout)); return $this->response; }
/** * @brief Disables a behavior in tests * * This function will overwrite the given behavior to a clean * instance of the ModelBehavior class so the behavior will act like it never * existed. * * @param mixed $behaviors Single behavior name or an array of names * * @return void */ public function disableBehavior($behaviors) { if (!is_array($behaviors)) { $behaviors = array($behaviors); } foreach ($behaviors as $behavior) { list($plugin, $name) = pluginSplit($behavior); $class = $name . 'Behavior'; $ModelBehavior = new ModelBehavior(); if (ClassRegistry::isKeySet($class)) { ClassRegistry::removeObject($class); if (!empty($plugin)) { ClassRegistry::removeObject($plugin . '.' . $class); } foreach (ClassRegistry::keys() as $key) { $instance = ClassRegistry::getObject($key); if (property_exists($instance, 'Behaviors')) { $instance->Behaviors->{$name} = $ModelBehavior; } } } ClassRegistry::addObject($class, $ModelBehavior); if (!empty($plugin)) { ClassRegistry::addObject($plugin . '.' . $class, $ModelBehavior); } } }
/** * testPersist method * * @access public * @return void */ function testPersist() { @unlink(CACHE . 'persistent' . DS . 'testmodel.php'); $this->assertFalse($this->object->testPersist('TestModel', null, $test)); $this->assertFalse($this->object->testPersist('TestModel', true, $test)); $this->assertTrue($this->object->testPersist('TestModel', null, $test)); $this->assertTrue(file_exists(CACHE . 'persistent' . DS . 'testmodel.php')); $this->assertTrue($this->object->testPersist('TestModel', true, $test)); $this->assertNull($this->object->TestModel); @unlink(CACHE . 'persistent' . DS . 'testmodel.php'); $model =& new ObjectTestModel(); $expected = ClassRegistry::keys(); ClassRegistry::flush(); $data = array('object_test_model' => $model); $this->assertFalse($this->object->testPersist('ObjectTestModel', true, $data)); $this->assertTrue(file_exists(CACHE . 'persistent' . DS . 'objecttestmodel.php')); $this->object->testPersist('ObjectTestModel', true, $model, 'registry'); $result = ClassRegistry::keys(); $this->assertEqual($result, $expected); $newModel = ClassRegistry::getObject('object_test_model'); $this->assertEqual('ObjectTestModel', $newModel->name); @unlink(CACHE . 'persistent' . DS . 'objecttestmodel.php'); }
/** * testImport * * @return void */ public function testImport() { $testSuiteDb = ConnectionManager::getDataSource('test'); $testSuiteConfig = $testSuiteDb->config; ConnectionManager::create('new_test_suite', array_merge($testSuiteConfig, array('prefix' => 'new_' . $testSuiteConfig['prefix']))); $newTestSuiteDb = ConnectionManager::getDataSource('new_test_suite'); $Source = new CakeTestFixtureTestFixture(); $Source->create($newTestSuiteDb); $Source->insert($newTestSuiteDb); $Fixture = new CakeTestFixtureDefaultImportFixture(); $Fixture->fields = $Fixture->records = null; $Fixture->import = array('model' => 'FixtureImportTestModel', 'connection' => 'new_test_suite'); $Fixture->init(); $this->assertEquals(array('id', 'name', 'created'), array_keys($Fixture->fields)); $keys = array_flip(ClassRegistry::keys()); $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys)); $Source->drop($newTestSuiteDb); }
/** * test the interactive side of bake. * * @return void */ public function testExecuteIntoInteractive() { $tables = $this->Task->listAll('test'); $article = array_search('bake_articles', $tables) + 1; $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; $this->Task->interactive = true; $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls($article, 'n', 'y', 'y', 'y', 'y', 'n', 'y')); $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true)); $this->Task->Test->expects($this->once())->method('bake'); $this->Task->Fixture->expects($this->once())->method('bake'); $filename = '/my/path/BakeArticle.php'; $this->Task->expects($this->once())->method('createFile')->with($filename, $this->stringContains('class BakeArticle')); $this->Task->execute(); $this->assertEquals(count(ClassRegistry::keys()), 0); $this->assertEquals(count(ClassRegistry::mapKeys()), 0); }
/** * Returns an HTML FORM element. * * ### Options: * * - `type` Form method defaults to POST * - `action` The controller action the form submits to, (optional). * - `url` The url the form submits to. Can be a string or a url array. If you use 'url' * you should leave 'action' undefined. * - `default` Allows for the creation of Ajax forms. * - `onsubmit` Used in conjunction with 'default' to create ajax forms. * - `inputDefaults` set the default $options for FormHelper::input(). Any options that would * be set when using FormHelper::input() can be set here. Options set with `inputDefaults` * can be overridden when calling input() * - `encoding` Set the accept-charset encoding for the form. Defaults to `Configure::read('App.encoding')` * * @access public * @param string $model The model object which the form is being defined for * @param array $options An array of html attributes and options. * @return string An formatted opening FORM tag. * @link http://book.cakephp.org/view/1384/Creating-Forms */ function create($model = null, $options = array()) { $created = $id = false; $append = ''; if (is_array($model) && empty($options)) { $options = $model; $model = null; } if (empty($model) && $model !== false && !empty($this->request['models'])) { $model = $this->request['models'][0]; $this->defaultModel = $this->request['models'][0]; } elseif (empty($model) && empty($this->request['models'])) { $model = false; } $models = ClassRegistry::keys(); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } if ($model !== false) { $object = $this->_introspectModel($model); $this->setEntity($model . '.', true); } $modelEntity = $this->model(); if ($model !== false && isset($this->fieldset[$modelEntity]['key'])) { $data = $this->fieldset[$modelEntity]; $recordExists = isset($this->request->data[$model]) && !empty($this->request->data[$model][$data['key']]) && !is_array($this->request->data[$model][$data['key']]); if ($recordExists) { $created = true; $id = $this->request->data[$model][$data['key']]; } } $options = array_merge(array('type' => $created && empty($options['action']) ? 'put' : 'post', 'action' => null, 'url' => null, 'default' => true, 'encoding' => strtolower(Configure::read('App.encoding')), 'inputDefaults' => array()), $options); $this->_inputDefaults = $options['inputDefaults']; unset($options['inputDefaults']); if (!isset($options['id'])) { $domId = isset($options['action']) ? $options['action'] : $this->request['action']; $options['id'] = $this->domId($domId . 'Form'); } if ($options['action'] === null && $options['url'] === null) { $options['action'] = $this->request->here(false); } elseif (empty($options['url']) || is_array($options['url'])) { if (empty($options['url']['controller'])) { if (!empty($model) && $model != $this->defaultModel) { $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model)); } elseif (!empty($this->request->params['controller'])) { $options['url']['controller'] = Inflector::underscore($this->request->params['controller']); } } if (empty($options['action'])) { $options['action'] = $this->request->params['action']; } $actionDefaults = array('plugin' => $this->plugin, 'controller' => $this->_View->viewPath, 'action' => $options['action']); $options['action'] = array_merge($actionDefaults, (array) $options['url']); if (empty($options['action'][0]) && !empty($id)) { $options['action'][0] = $id; } } elseif (is_string($options['url'])) { $options['action'] = $options['url']; } unset($options['url']); switch (strtolower($options['type'])) { case 'get': $htmlAttributes['method'] = 'get'; break; case 'file': $htmlAttributes['enctype'] = 'multipart/form-data'; $options['type'] = $created ? 'put' : 'post'; case 'post': case 'put': case 'delete': $append .= $this->hidden('_method', array('name' => '_method', 'value' => strtoupper($options['type']), 'id' => null)); default: $htmlAttributes['method'] = 'post'; break; } $this->requestType = strtolower($options['type']); $htmlAttributes['action'] = $this->url($options['action']); unset($options['type'], $options['action']); if ($options['default'] == false) { if (isset($htmlAttributes['onSubmit']) || isset($htmlAttributes['onsubmit'])) { $htmlAttributes['onsubmit'] .= ' event.returnValue = false; return false;'; } else { $htmlAttributes['onsubmit'] = 'event.returnValue = false; return false;'; } } if (!empty($options['encoding'])) { $htmlAttributes['accept-charset'] = $options['encoding']; unset($options['encoding']); } unset($options['default']); $htmlAttributes = array_merge($options, $htmlAttributes); $this->fields = array(); if (isset($this->request->params['_Token']) && !empty($this->request->params['_Token'])) { $append .= $this->hidden('_Token.key', array('value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand())); } if (!empty($append)) { $append = $this->Html->useTag('block', ' style="display:none;"', $append); } $this->setEntity($model . '.', true); return $this->Html->useTag('form', $htmlAttributes) . $append; }
/** * Return all vaidation errors. * * @return array */ public function validationErrors() { $return = array(); $models = ClassRegistry::keys(); foreach ($models as $currentModel) { $currentObject = ClassRegistry::getObject($currentModel); if ($currentObject instanceof Model) { $return[$currentObject->alias] = $currentObject->validationErrors; } } return $return; }
/** * Instantiates the correct view class, hands it its data, and uses it to render the view output. * * @param string $action Action name to render * @param string $layout Layout to use * @param string $file File to use for rendering * @return string Full output string of view contents * @access public * @link http://book.cakephp.org/view/428/render */ function render($action = null, $layout = null, $file = null) { $this->beforeRender(); $viewClass = $this->view; if ($this->view != 'View') { if (strpos($viewClass, '.') !== false) { list($plugin, $viewClass) = explode('.', $viewClass); } $viewClass = $viewClass . 'View'; App::import('View', $this->view); } $this->Component->beforeRender($this); $this->params['models'] = $this->modelNames; if (Configure::read() > 2) { $this->set('cakeDebug', $this); } $View =& new $viewClass($this); if (!empty($this->modelNames)) { $models = array(); foreach ($this->modelNames as $currentModel) { if (isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model')) { $models[] = Inflector::underscore($currentModel); } $isValidModel = isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model') && !empty($this->{$currentModel}->validationErrors); if ($isValidModel) { $View->validationErrors[Inflector::camelize($currentModel)] =& $this->{$currentModel}->validationErrors; } } $models = array_diff(ClassRegistry::keys(), $models); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $View->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } } $this->autoRender = false; $this->output .= $View->render($action, $layout, $file); return $this->output; }
/** * Gets an instance of the view object & prepares it for rendering the output, then * asks the view to actualy do the job. * * @param string $action Action name to render * @param string $layout Layout to use * @param string $file File to use for rendering * @return boolean Success * @access public */ function render($action = null, $layout = null, $file = null) { $this->beforeRender(); $viewClass = $this->view; if ($this->view != 'View') { if (strpos($viewClass, '.') !== false) { list($plugin, $viewClass) = explode('.', $viewClass); } $viewClass = $viewClass . 'View'; App::import('View', $this->view); } foreach ($this->components as $c) { $path = preg_split('/\\/|\\./', $c); $c = $path[count($path) - 1]; if (isset($this->{$c}) && is_object($this->{$c}) && is_callable(array($this->{$c}, 'beforeRender'))) { if (!array_key_exists('enabled', get_object_vars($this->{$c})) || $this->{$c}->enabled == true) { $this->{$c}->beforeRender($this); } } } $this->params['models'] = $this->modelNames; if (Configure::read() > 2) { $this->set('cakeDebug', $this); } $this->__viewClass =& new $viewClass($this); if (!empty($this->modelNames)) { $models = array(); foreach ($this->modelNames as $currentModel) { if (isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model')) { $models[] = Inflector::underscore($currentModel); } if (isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model') && !empty($this->{$currentModel}->validationErrors)) { $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $this->{$currentModel}->validationErrors; } } $models = array_diff(ClassRegistry::keys(), $models); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } } $this->autoRender = false; return $this->__viewClass->render($action, $layout, $file); }
/** * Tests an action using the controller itself and skipping the dispatcher, and * returning the view vars. * * Since `CakeTestCase::testAction` was causing so many problems and is * incredibly slow, it is overwritten here to go about it a bit differently. * Import `ExtendedTestCase` from 'Lib' and extend test cases using `ExtendedTestCase` * instead to gain this functionality. * * For backwards compatibility with the original `CakeTestCase::testAction`, set * `testController` to `null`. * * ### Options: * - `data` Data to pass to the controller * * ### Limitations: * - only reinstantiates the default model * - not 100% complete, i.e., some callbacks may not be fired like they would * if regularly called through the dispatcher * * @param string $url The url to test * @param array $options A list of options * @return array The view vars * @link http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way * @link http://mark-story.com/posts/view/testing-cakephp-controllers-mock-objects-edition * @link http://www.42pixels.com/blog/testing-controllers-the-slightly-less-hard-way */ function testAction($url = '', $options = array()) { if (is_null($this->testController)) { return parent::testAction($url, $options); } $Controller = $this->testController; // reset parameters ClassRegistry::flush(); $Controller->passedArgs = array(); $Controller->params = array(); $Controller->url = null; $Controller->action = null; $Controller->viewVars = array(); $keys = ClassRegistry::keys(); foreach ($keys as $key) { if (is_a(ClassRegistry::getObject(Inflector::camelize($key)), 'Model')) { ClassRegistry::getObject(Inflector::camelize($key))->create(false); } } $Controller->Session->delete('Message'); $Controller->activeUser = null; $default = array('data' => array(), 'method' => 'post'); $options = array_merge($default, $options); // set up the controller based on the url $urlParams = Router::parse($url); $extra = array_diff_key($options, array('data' => null, 'method' => null, 'return' => null)); $urlParams = array_merge($urlParams, $extra); $action = $urlParams['action']; $prefix = null; $urlParams['url']['url'] = $url; if (strtolower($options['method']) == 'get') { $urlParams['url'] = array_merge($options['data'], $urlParams['url']); } else { $Controller->data = $options['data']; } if (isset($urlParams['prefix'])) { $action = $urlParams['prefix'] . '_' . $action; $prefix = $urlParams['prefix'] . '/'; } $Controller->passedArgs = $urlParams['named']; $Controller->params = $urlParams; $Controller->url = $urlParams; $Controller->action = $prefix . $urlParams['plugin'] . '/' . $urlParams['controller'] . '/' . $urlParams['action']; // only initialize the components once if ($this->_componentsInitialized === false) { $this->_componentsInitialized = true; $Controller->Component->initialize($Controller); } $Controller->beforeFilter(); $Controller->Component->startup($Controller); call_user_func_array(array(&$Controller, $action), $urlParams['pass']); $Controller->beforeRender(); $Controller->Component->triggerCallback('beforeRender', $Controller); return $Controller->viewVars; }
/** * test that execute passes runs bake depending with named model. * * @return void * @access public */ function testBakeModel() { $this->Task->connection = 'test_suite'; $this->Task->path = '/my/path/'; $filename = '/my/path/article.php'; $this->Task->setReturnValue('_checkUnitTest', 1); $this->Task->expectAt(0, 'createFile', array($filename, new PatternExpectation('/class Article extends AppModel/'))); $model =& new Model(array('name' => 'Article', 'table' => 'articles', 'ds' => 'test_suite')); $this->Task->bake($model); $this->assertEqual(count(ClassRegistry::keys()), 0); $this->assertEqual(count(ClassRegistry::mapKeys()), 0); }
/** * Iterates through an array and attaches those models to $Model * * This function is here solely to trick `Controller::paginate()` into thinking * that the models in $linked are directly and should only be used if the 'link' * key is present * * @param Model $Model * @param array $linked * @see LinkableBehavior */ protected function _attachLinkedModels(&$Model, $linked) { $keys = ClassRegistry::keys(); $linked = Set::normalize($linked); foreach ($linked as $_model => $attrs) { if (in_array(Inflector::underscore($_model), $keys)) { $Model->{$_model} = ClassRegistry::init($_model); } if (!is_array($attrs) && in_array(Inflector::underscore($attrs), $keys)) { $Model->{$attrs} = ClassRegistry::init($attrs); } elseif (is_array($attrs)) { $this->_attachLinkedModels($Model, $attrs); } } }
/** * Instantiates the correct view class, hands it its data, and uses it to render the view output. * * @param string $view View to use for rendering * @param string $layout Layout to use * @return string Full output string of view contents * @link http://book.cakephp.org/view/980/render */ public function render($view = null, $layout = null) { $this->beforeRender(); $this->Components->trigger('beforeRender', array(&$this)); $viewClass = $this->viewClass; if ($this->viewClass != 'View') { list($plugin, $viewClass) = pluginSplit($viewClass); $viewClass = $viewClass . 'View'; App::import('View', $this->viewClass); } $this->request->params['models'] = $this->modelNames; $View = new $viewClass($this); if (!empty($this->modelNames)) { $models = array(); foreach ($this->modelNames as $currentModel) { if (isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model')) { $models[] = Inflector::underscore($currentModel); } $isValidModel = isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model') && !empty($this->{$currentModel}->validationErrors); if ($isValidModel) { $View->validationErrors[Inflector::camelize($currentModel)] =& $this->{$currentModel}->validationErrors; } } $models = array_diff(ClassRegistry::keys(), $models); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject = ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $View->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } } $this->autoRender = false; $this->View = $View; return $this->response->body($View->render($view, $layout)); }
/** * testInit * * @access public * @return void */ function testInit() { $Fixture =& new CakeTestFixtureTestFixture(); unset($Fixture->table); $Fixture->init(); $this->assertEqual($Fixture->table, 'fixture_tests'); $this->assertEqual($Fixture->primaryKey, 'id'); $Fixture =& new CakeTestFixtureTestFixture(); $Fixture->primaryKey = 'my_random_key'; $Fixture->init(); $this->assertEqual($Fixture->primaryKey, 'my_random_key'); $this->_initDb(); $Source =& new CakeTestFixtureTestFixture(); $Source->create($this->db); $Source->insert($this->db); $Fixture =& new CakeTestFixtureImportFixture(); $expected = array('id', 'name', 'created'); $this->assertEqual(array_keys($Fixture->fields), $expected); $db =& ConnectionManager::getDataSource('test_suite'); $config = $db->config; $config['prefix'] = 'fixture_test_suite_'; ConnectionManager::create('fixture_test_suite', $config); $Fixture->fields = $Fixture->records = null; $Fixture->import = array('table' => 'fixture_tests', 'connection' => 'test_suite', 'records' => true); $Fixture->init(); $this->assertEqual(count($Fixture->records), count($Source->records)); $Fixture =& new CakeTestFixtureImportFixture(); $Fixture->fields = $Fixture->records = null; $Fixture->import = array('model' => 'FixtureImportTestModel', 'connection' => 'test_suite'); $Fixture->init(); $this->assertEqual(array_keys($Fixture->fields), array('id', 'name', 'created')); //assert that model has been removed from registry, stops infinite loops. $keys = array_flip(ClassRegistry::keys()); $this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys)); $Source->drop($this->db); }
/** * test the interactive side of bake. * * @return void * @access public */ function testExecuteIntoInteractive() { $this->Task->connection = 'test_suite'; $this->Task->path = '/my/path/'; $this->Task->interactive = true; $this->Task->setReturnValueAt(0, 'in', '1'); //choose article $this->Task->setReturnValueAt(1, 'in', 'n'); //no validation $this->Task->setReturnValueAt(2, 'in', 'y'); //yes to associations $this->Task->setReturnValueAt(3, 'in', 'y'); //yes to comment relation $this->Task->setReturnValueAt(4, 'in', 'y'); //yes to user relation $this->Task->setReturnValueAt(5, 'in', 'y'); //yes to tag relation $this->Task->setReturnValueAt(6, 'in', 'n'); //no to additional assocs $this->Task->setReturnValueAt(7, 'in', 'y'); //yes to looksGood? $this->Task->setReturnValue('_checkUnitTest', true); $this->Task->Test->expectOnce('bake'); $this->Task->Fixture->expectOnce('bake'); $filename = '/my/path/article.php'; $this->Task->expectOnce('createFile'); $this->Task->expectAt(0, 'createFile', array($filename, new PatternExpectation('/class Article/'))); $this->Task->execute(); $this->assertEqual(count(ClassRegistry::keys()), 0); $this->assertEqual(count(ClassRegistry::mapKeys()), 0); }
/** * testPersist method * * @access public * @return void */ function testPersist() { ClassRegistry::flush(); $cacheDisable = Configure::read('Cache.disable'); Configure::write('Cache.disable', false); @unlink(CACHE . 'persistent' . DS . 'testmodel.php'); $test = new stdClass(); $this->assertFalse($this->object->testPersist('TestModel', null, $test)); $this->assertFalse($this->object->testPersist('TestModel', true, $test)); $this->assertTrue($this->object->testPersist('TestModel', null, $test)); $this->assertTrue(file_exists(CACHE . 'persistent' . DS . 'testmodel.php')); $this->assertTrue($this->object->testPersist('TestModel', true, $test)); $this->assertEqual($this->object->TestModel, $test); @unlink(CACHE . 'persistent' . DS . 'testmodel.php'); $model =& new ObjectTestModel(); $expected = ClassRegistry::keys(); ClassRegistry::flush(); $data = array('object_test_model' => $model); $this->assertFalse($this->object->testPersist('ObjectTestModel', true, $data)); $this->assertTrue(file_exists(CACHE . 'persistent' . DS . 'objecttestmodel.php')); $this->object->testPersist('ObjectTestModel', true, $model, 'registry'); $result = ClassRegistry::keys(); $this->assertEqual($result, $expected); $newModel = ClassRegistry::getObject('object_test_model'); $this->assertEqual('ObjectTestModel', $newModel->name); @unlink(CACHE . 'persistent' . DS . 'objecttestmodel.php'); Configure::write('Cache.disable', $cacheDisable); }
/** * Returns an HTML FORM element. * * Options: * * - 'type' Form method defaults to POST * - 'action' The Action the form submits to. Can be a string or array, * - 'url' The url the form submits to. Can be a string or a url array, * - 'default' Allows for the creation of Ajax forms. * - 'onsubmit' Used in conjunction with 'default' to create ajax forms. * * @access public * @param string $model The model object which the form is being defined for * @param array $options An array of html attributes and options. * @return string An formatted opening FORM tag. */ function create($model = null, $options = array()) { $defaultModel = null; $view =& ClassRegistry::getObject('view'); if (is_array($model) && empty($options)) { $options = $model; $model = null; } if (empty($model) && $model !== false && !empty($this->params['models'])) { $model = $this->params['models'][0]; $defaultModel = $this->params['models'][0]; } elseif (empty($model) && empty($this->params['models'])) { $model = false; } elseif (is_string($model) && strpos($model, '.') !== false) { $path = explode('.', $model); $model = $path[count($path) - 1]; } if (ClassRegistry::isKeySet($model)) { $object =& ClassRegistry::getObject($model); } $models = ClassRegistry::keys(); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } $this->setEntity($model . '.', true); $append = ''; $created = $id = false; if (isset($object)) { $fields = $object->schema(); foreach ($fields as $key => $value) { unset($fields[$key]); $fields[$model . '.' . $key] = $value; } if (!empty($object->hasAndBelongsToMany)) { foreach ($object->hasAndBelongsToMany as $alias => $assocData) { $fields[$alias] = array('type' => 'multiple'); } } $validates = array(); if (!empty($object->validate)) { foreach ($object->validate as $validateField => $validateProperties) { if (is_array($validateProperties)) { $dims = Set::countDim($validateProperties); if ($dims == 1 && !isset($validateProperties['required']) || array_key_exists('required', $validateProperties) && $validateProperties['required'] !== false) { $validates[] = $validateField; } elseif ($dims > 1) { foreach ($validateProperties as $rule => $validateProp) { if (is_array($validateProp) && (array_key_exists('required', $validateProp) && $validateProp['required'] !== false)) { $validates[] = $validateField; } } } } } } $key = $object->primaryKey; $this->fieldset = compact('fields', 'key', 'validates'); } $data = $this->fieldset; $recordExists = isset($this->data[$model]) && isset($this->data[$model][$data['key']]) && !empty($this->data[$model][$data['key']]); if ($recordExists) { $created = true; $id = $this->data[$model][$data['key']]; } $options = array_merge(array('type' => $created && empty($options['action']) ? 'put' : 'post', 'action' => null, 'url' => null, 'default' => true), $options); if (empty($options['url']) || is_array($options['url'])) { if (empty($options['url']['controller'])) { if (!empty($model) && $model != $defaultModel) { $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model)); } elseif (!empty($this->params['controller'])) { $options['url']['controller'] = Inflector::underscore($this->params['controller']); } } if (empty($options['action'])) { $options['action'] = $created ? 'edit' : 'add'; } $actionDefaults = array('plugin' => $this->plugin, 'controller' => $view->viewPath, 'action' => $options['action'], 'id' => $id); if (!empty($options['action']) && !isset($options['id'])) { $options['id'] = $model . Inflector::camelize($options['action']) . 'Form'; } $options['action'] = array_merge($actionDefaults, (array) $options['url']); } elseif (is_string($options['url'])) { $options['action'] = $options['url']; } unset($options['url']); switch (strtolower($options['type'])) { case 'get': $htmlAttributes['method'] = 'get'; break; case 'file': $htmlAttributes['enctype'] = 'multipart/form-data'; $options['type'] = $created ? 'put' : 'post'; case 'post': case 'put': case 'delete': $append .= $this->hidden('_method', array('name' => '_method', 'value' => strtoupper($options['type']), 'id' => null)); default: $htmlAttributes['method'] = 'post'; break; } $this->requestType = strtolower($options['type']); $htmlAttributes['action'] = $this->url($options['action']); unset($options['type'], $options['action']); if ($options['default'] == false) { if (isset($htmlAttributes['onSubmit']) || isset($htmlAttributes['onsubmit'])) { $htmlAttributes['onsubmit'] .= ' event.returnValue = false; return false;'; } else { $htmlAttributes['onsubmit'] = 'event.returnValue = false; return false;'; } } unset($options['default']); $htmlAttributes = array_merge($options, $htmlAttributes); if (isset($this->params['_Token']) && !empty($this->params['_Token'])) { $append .= $this->hidden('_Token.key', array('value' => $this->params['_Token']['key'], 'id' => 'Token' . mt_rand())); } if (!empty($append)) { $append = sprintf($this->Html->tags['fieldset'], ' style="display:none;"', $append); } $this->setEntity($model . '.', true); $attributes = $this->_parseAttributes($htmlAttributes, null, ''); return $this->output(sprintf($this->Html->tags['form'], $attributes)) . $append; }
/** * Gets an instance of the view object and prepares it for rendering the output, then * asks the view to actualy do the job. * * @param string $action * @param string $layout * @param string $file * @return controllers related views * @access public */ function render($action = null, $layout = null, $file = null) { $viewClass = $this->view; if ($this->view != 'View') { $viewClass = $this->view . 'View'; loadView($this->view); } $this->beforeRender(); $this->__viewClass =& new $viewClass($this); if (!empty($this->modelNames)) { $models = array(); foreach ($this->modelNames as $currentModel) { if (isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model')) { $models[] = Inflector::underscore($currentModel); } if (isset($this->{$currentModel}) && is_a($this->{$currentModel}, 'Model') && !empty($this->{$currentModel}->validationErrors)) { $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $this->{$currentModel}->validationErrors; } } $models = array_diff(ClassRegistry::keys(), $models); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } } $this->autoRender = false; return $this->__viewClass->render($action, $layout, $file); }
/** * testPersistWithBehaviorAndRequestAction method * * @see testPersistWithBehavior * @access public * @return void */ function testPersistWithBehaviorAndRequestAction() { ClassRegistry::flush(); $cacheDisable = Configure::read('Cache.disable'); Configure::write('Cache.disable', false); $this->assertFalse(class_exists('ContainableBehavior')); Configure::write('modelPaths', array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS)); Configure::write('behaviorPaths', array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS . 'behaviors' . DS)); $this->assertFalse(class_exists('PersistOneBehaviorBehavior')); $this->assertFalse(class_exists('PersistTwoBehaviorBehavior')); $Controller = new RequestActionPersistentController(); $Controller->persistModel = true; $Controller->constructClasses(); $this->assertTrue(file_exists(CACHE . 'persistent' . DS . 'persisterone.php')); $this->assertTrue(file_exists(CACHE . 'persistent' . DS . 'persisteroneregistry.php')); $keys = ClassRegistry::keys(); $this->assertEqual($keys, array('persister_one', 'comment', 'persister_one_behavior_behavior')); ob_start(); $Controller->set('content_for_layout', 'cool'); $Controller->render('index', 'ajax', '/layouts/ajax'); $result = ob_get_clean(); $keys = ClassRegistry::keys(); $this->assertEqual($keys, array('persister_one', 'comment', 'persister_one_behavior_behavior', 'view')); $result = $this->object->requestAction('/request_action_persistent/index'); $expected = 'This is a test'; $this->assertEqual($result, $expected); @unlink(CACHE . 'persistent' . DS . 'persisterone.php'); @unlink(CACHE . 'persistent' . DS . 'persisteroneregistry.php'); $Controller = new RequestActionPersistentController(); $Controller->persistModel = true; $Controller->constructClasses(); @unlink(CACHE . 'persistent' . DS . 'persisterone.php'); @unlink(CACHE . 'persistent' . DS . 'persisteroneregistry.php'); Configure::write('Cache.disable', $cacheDisable); }
/** * test the interactive side of bake. * * @return void */ public function testExecuteIntoInteractive() { $count = count($this->Task->listAll('test')); if ($count != count($this->fixtures)) { $this->markTestSkipped('Additional tables detected.'); } $this->Task->connection = 'test'; $this->Task->path = '/my/path/'; $this->Task->interactive = true; $this->Task->expects($this->any())->method('in')->will($this->onConsecutiveCalls('1', 'n', 'y', 'y', 'y', 'y', 'n', 'y')); $this->Task->expects($this->once())->method('_checkUnitTest')->will($this->returnValue(true)); $this->Task->Test->expects($this->once())->method('bake'); $this->Task->Fixture->expects($this->once())->method('bake'); $filename = '/my/path/BakeArticle.php'; $this->Task->expects($this->once())->method('createFile')->with($filename, $this->stringContains('class BakeArticle')); $this->Task->execute(); $this->assertEqual(count(ClassRegistry::keys()), 0); $this->assertEqual(count(ClassRegistry::mapKeys()), 0); }
/** * creating test subjects should clear the registry so the registry is always fresh * * @return void */ public function testRegistryClearWhenBuildingTestObjects() { ClassRegistry::flush(); $model = ClassRegistry::init('TestTaskComment'); $model->bindModel(array('belongsTo' => array('Random' => array('className' => 'TestTaskArticle', 'foreignKey' => 'article_id')))); $keys = ClassRegistry::keys(); $this->assertTrue(in_array('test_task_comment', $keys)); $object = $this->Task->buildTestSubject('Model', 'TestTaskComment'); $keys = ClassRegistry::keys(); $this->assertFalse(in_array('random', $keys)); }
/** * Instantiates the correct view class, hands it its data, and uses it to render the view output. * * @param string $view View to use for rendering * @param string $layout Layout to use * @return CakeResponse A response object containing the rendered view. * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::render */ public function render($view = null, $layout = null) { $this->beforeRender(); $this->Components->trigger('beforeRender', array(&$this)); $viewClass = $this->viewClass; if ($this->viewClass != 'View') { list($plugin, $viewClass) = pluginSplit($viewClass, true); $viewClass = $viewClass . 'View'; App::uses($viewClass, $plugin . 'View'); } $View = new $viewClass($this); if (!empty($this->uses)) { foreach ($this->uses as $model) { list($plugin, $className) = pluginSplit($model); $this->request->params['models'][$className] = compact('plugin', 'className'); } } if (!empty($this->modelClass) && ($this->uses === false || $this->uses === array())) { $this->request->params['models'][$this->modelClass] = array('plugin' => $this->plugin, 'className' => $this->modelClass); } $models = ClassRegistry::keys(); foreach ($models as $currentModel) { $currentObject = ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model')) { $className = get_class($currentObject); list($plugin) = pluginSplit(App::location($className)); $this->request->params['models'][$currentObject->alias] = compact('plugin', 'className'); $View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors; } } $this->autoRender = false; $this->View = $View; $this->response->body($View->render($view, $layout)); return $this->response; }
/** * Instantiates the correct view class, hands it its data, and uses it to render the view output. * * @param string $view View to use for rendering * @param string $layout Layout to use * @return CakeResponse A response object containing the rendered view. * @triggers Controller.beforeRender $this * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::render */ public function render($view = null, $layout = null) { $event = new CakeEvent('Controller.beforeRender', $this); $this->getEventManager()->dispatch($event); if ($event->isStopped()) { $this->autoRender = false; return $this->response; } if (!empty($this->uses) && is_array($this->uses)) { foreach ($this->uses as $model) { list($plugin, $className) = pluginSplit($model); $this->request->params['models'][$className] = compact('plugin', 'className'); } } $this->View = $this->_getViewObject(); $models = ClassRegistry::keys(); foreach ($models as $currentModel) { $currentObject = ClassRegistry::getObject($currentModel); if ($currentObject instanceof Model) { $className = get_class($currentObject); list($plugin) = pluginSplit(App::location($className)); $this->request->params['models'][$currentObject->alias] = compact('plugin', 'className'); $this->View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors; } } $this->autoRender = false; $this->response->body($this->View->render($view, $layout)); return $this->response; }
/** * Returns an HTML FORM element. * * @access public * @param string $model The model object which the form is being defined for * @param array $options * @return string An formatted opening FORM tag. */ function create($model = null, $options = array()) { $defaultModel = null; $data = $this->fieldset; $view =& ClassRegistry::getObject('view'); if (is_array($model) && empty($options)) { $options = $model; $model = null; } if (empty($model) && $model !== false && !empty($this->params['models'])) { $model = $this->params['models'][0]; $defaultModel = $this->params['models'][0]; } elseif (empty($model) && empty($this->params['models'])) { $model = false; } elseif (is_string($model) && (strpos($model, '/') !== false || strpos($model, '.') !== false)) { $path = preg_split('/\\/|\\./', $model); $model = $path[count($path) - 1]; } if (ClassRegistry::isKeySet($model)) { $object =& ClassRegistry::getObject($model); } $models = ClassRegistry::keys(); foreach ($models as $currentModel) { if (ClassRegistry::isKeySet($currentModel)) { $currentObject =& ClassRegistry::getObject($currentModel); if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) { $this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors; } } } $this->setEntity($model . '.', true); $append = ''; $created = $id = false; if (isset($object)) { $fields = $object->schema(); if (empty($fields)) { trigger_error(__('(FormHelper::create) Unable to use model field data. If you are using a model without a database table, try implementing schema()', true), E_USER_WARNING); } if (!empty($object->hasAndBelongsToMany)) { foreach ($object->hasAndBelongsToMany as $alias => $assocData) { $fields[$alias] = array('type' => 'multiple'); } } $this->fieldset = array('fields' => $fields, 'key' => $object->primaryKey, 'validates' => ife(empty($object->validate), array(), array_keys($object->validate))); } if (isset($this->data[$model]) && isset($this->data[$model][$data['key']]) && !empty($this->data[$model][$data['key']])) { $created = true; $id = $this->data[$model][$data['key']]; } $options = array_merge(array('type' => $created && empty($options['action']) ? 'put' : 'post', 'action' => null, 'url' => null, 'default' => true), $options); if (empty($options['url']) || is_array($options['url'])) { $options = (array) $options; if (!empty($model) && $model != $defaultModel) { $controller = Inflector::underscore(Inflector::pluralize($model)); } else { $controller = Inflector::underscore($this->params['controller']); } if (empty($options['action'])) { $options['action'] = ife($created, 'edit', 'add'); } $actionDefaults = array('plugin' => $this->plugin, 'controller' => $controller, 'action' => $options['action'], 'id' => $id); if (!empty($options['action']) && !isset($options['id'])) { $options['id'] = $model . Inflector::camelize($options['action']) . 'Form'; } $options['action'] = array_merge($actionDefaults, (array) $options['url']); } elseif (is_string($options['url'])) { $options['action'] = $options['url']; } unset($options['url']); switch (strtolower($options['type'])) { case 'get': $htmlAttributes['method'] = 'get'; break; case 'file': $htmlAttributes['enctype'] = 'multipart/form-data'; $options['type'] = ife($created, 'put', 'post'); case 'post': case 'put': case 'delete': $append .= $this->hidden('_method', array('name' => '_method', 'value' => strtoupper($options['type']), 'id' => null)); default: $htmlAttributes['method'] = 'post'; break; } $this->requestType = strtolower($options['type']); $htmlAttributes['action'] = $this->url($options['action']); unset($options['type'], $options['action']); if ($options['default'] == false) { if (isset($htmlAttributes['onSubmit'])) { $htmlAttributes['onSubmit'] .= ' event.returnValue = false; return false;'; } else { $htmlAttributes['onSubmit'] = 'event.returnValue = false; return false;'; } } unset($options['default']); $htmlAttributes = array_merge($options, $htmlAttributes); if (isset($this->params['_Token']) && !empty($this->params['_Token'])) { $append .= $this->hidden('_Token.key', array('value' => $this->params['_Token']['key'], 'id' => 'Token' . mt_rand())); } if (!empty($append)) { $append = '<fieldset style="display:none;">' . $append . '</fieldset>'; } $this->setEntity($model . '.', true); return $this->output(sprintf($this->Html->tags['form'], $this->Html->_parseAttributes($htmlAttributes, null, ''))) . $append; }
/** * Tests an action using the controller itself and skipping the dispatcher, and * returning the view vars. * * Since `CakeTestCase::testAction` was causing so many problems and is * incredibly slow, it is overwritten here to go about it a bit differently. * Import `CoreTestCase` from 'Lib' and extend test cases using `CoreTestCase` * instead to gain this functionality. * * For backwards compatibility with the original `CakeTestCase::testAction`, set * `testController` to `null`. * * ### Options: * - `data` Data to pass to the controller * * ### Limitations: * - only reinstantiates the default model * - not 100% complete, i.e., some callbacks may not be fired like they would * if regularly called through the dispatcher * * @param string $url The url to test * @param array $options A list of options * @return array The view vars * @link http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way */ public function testAction($url = '', $options = array()) { if (is_null($this->testController)) { return parent::testAction($url, $options); } $Controller = $this->testController; // reset parameters $Controller->passedArgs = array(); $Controller->params = array(); $Controller->url = null; $Controller->action = null; $Controller->viewVars = array(); $keys = ClassRegistry::keys(); foreach ($keys as $key) { if (is_a(ClassRegistry::getObject(Inflector::camelize($key)), 'Model')) { ClassRegistry::getObject(Inflector::camelize($key))->create(false); } } $Controller->Session->delete('Message'); $Controller->activeUser = null; $default = array('data' => array(), 'method' => 'post'); $options = array_merge($default, $options); // set up the controller based on the url $urlParams = Router::parse($url); if (stripos('http', $url) === false) { $url = 'http://localhost/' . ltrim($url, '/'); } parse_str(parse_url($url, PHP_URL_QUERY), $queryParams); if (!isset($urlParams['url'])) { $urlParams['url'] = array(); } $urlParams['url'] = array_merge($urlParams['url'], $queryParams); if (strtolower($options['method']) == 'get') { $urlParams['url'] = array_merge($options['data'], $urlParams['url']); } else { $Controller->data = $options['data']; } $Controller->passedArgs = $urlParams['named']; $Controller->params = $urlParams; $Controller->params['url']['url'] = $url; $Controller->url = $urlParams; $Controller->action = $urlParams['plugin'] . '/' . $urlParams['controller'] . '/' . $urlParams['action']; $Controller->Component->initialize($Controller); if (isset($Controller->Toolbar)) { $Controller->Toolbar->enabled = false; } // configure auth if (isset($Controller->Auth)) { $Controller->Auth->initialize($Controller); if (!$Controller->Session->check('Auth.User') && !$Controller->Session->check('User')) { $this->su(); } } // configure acl if (isset($Controller->Acl)) { $core =& Core::getInstance(); $core->Acl = new MockAclComponent(); $core->Acl->__construct(); $core->Acl->enabled = true; $core->Acl->setReturnValue('check', true); } $Controller->beforeFilter(); $Controller->Component->startup($Controller); call_user_func_array(array(&$Controller, $urlParams['action']), $urlParams['pass']); $Controller->beforeRender(); $Controller->Component->triggerCallback('beforeRender', $Controller); // trick debugkit into skipping its __destruct method which clutters up the response if (class_exists('DebugKitDebugger')) { $_debugkit =& DebugKitDebugger::getInstance(); $_debugkit->__benchmarks = null; } return $Controller->viewVars; }
/** * Converts POST'ed form data to a model conditions array, suitable for use in a Model::find() call. * * @param array $data POST'ed data organized by model and field * @param mixed $op A string containing an SQL comparison operator, or an array matching operators * to fields * @param string $bool SQL boolean operator: AND, OR, XOR, etc. * @param boolean $exclusive If true, and $op is an array, fields not included in $op will not be * included in the returned conditions * @return array An array of model conditions * @link http://book.cakephp.org/view/989/postConditions */ public function postConditions($data = array(), $op = null, $bool = 'AND', $exclusive = false) { unset($data['_Token']); $registered = ClassRegistry::keys(); $bools = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&'); $cond = array(); if ($op === null) { $op = ''; } $arrayOp = is_array($op); foreach ($data as $model => $fields) { if (is_array($fields)) { foreach ($fields as $field => $value) { if (is_array($value) && in_array(strtolower($field), $registered)) { $cond += (array) self::postConditions(array($field => $value), $op, $bool, $exclusive); } else { // check for boolean keys if (in_array(strtolower($model), $bools)) { $key = $field; } else { $key = $model . '.' . $field; } // check for habtm [Publication][Publication][0] = 1 if ($model == $field) { // should get PK $key = $model . '.id'; } $fieldOp = $op; if ($arrayOp) { if (array_key_exists($key, $op)) { $fieldOp = $op[$key]; } elseif (array_key_exists($field, $op)) { $fieldOp = $op[$field]; } else { $fieldOp = false; } } if ($exclusive && $fieldOp === false) { continue; } $fieldOp = strtoupper(trim($fieldOp)); if (is_array($value) || is_numeric($value)) { $fieldOp = '='; } if ($fieldOp === 'LIKE') { $key = $key . ' LIKE'; $value = '%' . $value . '%'; } elseif ($fieldOp && $fieldOp != '=') { $key = $key . ' ' . $fieldOp; } if ($value !== '%%') { $cond[$key] = $value; } } } } } if ($bool != null && strtoupper($bool) != 'AND') { $cond = array($bool => $cond); } return $cond; }