function parse($html = null, $blockName = 'document', $blockParams = null) { SlConfigure::write('Asset.js.footer.emailDefuscator.after', <<<end jQuery.fn.defuscate = function(settings) { settings = jQuery.extend({link: true}, settings); regex = /\\b([A-Z0-9._%-]+)\\([^)]+\\)((?:[A-Z0-9-]+\\.?))+\\([^)]+\\)([A-Z]{2,6})\\b/gi; mailto = '<a href="mailto:\$1@\$2.\$3">\$1@\$2.\$3</a>'; plain = "\$1@\$2.\$3"; return this.each(function() { defuscated = jQuery(this).html().replace(regex, settings.link ? mailto : plain) jQuery(this).html(defuscated); }); } jQuery(function() { jQuery('.sl-email').defuscate(); }); end ); if (empty($html)) { $html = $this->_getVar('CmsContactForm.email'); } if (empty($html)) { return; } list($user, $domain) = explode('@', $html, 2); $parts = explode('.', $domain); $zone = array_pop($parts); $domain = implode('.', $parts); $params = isset($blockParams['params']) ? $blockParams['params'] : null; $this->vars = compact('user', 'domain', 'zone', 'params'); return parent::parse(null, $blockName); }
/** * If we work with multiple collections, * it is necessary cleanup old data everywhere before saving * * @param string $locale */ protected function _cleanup($name, $locale = null) { $collections = SlConfigure::read(null, 'populated', true); foreach ($collections as $collection) { SlConfigure::delete($name, true, $locale ? "{$collection}.{$locale}" : $collection); } }
function __construct() { $db = SlConfigure::read('Db'); foreach ($db as $name => $value) { $this->{$name} = $value; } }
function parse($html = null, $blockName = 'document', $blockParams = null) { if (empty($html)) { return; } $images = Set::normalize($html, false); foreach ($images as &$image) { if (!strpos($image, '://') && $image[0] != '/') { $image = "img/{$image}"; } $image = $this->_getHelper('SlHtml')->webroot($image); SlConfigure::append("Asset.js.ready", "\$.preloadImages({$images})"); } SlConfigure::write('Asset.js.footer.imagePreloader.after', <<<end jQuery.preLoadImagesCache = []; // Arguments are image paths relative to the current page. jQuery.preLoadImages = function() { var args_len = arguments.length; for (var i = args_len; i--;) { var cacheImage = document.createElement('img'); cacheImage.src = arguments[i]; jQuery.preLoadImagesCache.push(cacheImage); } } end ); }
public static function started() { if (self::$_started === null) { $options = SlConfigure::read('Sl.session'); session_write_close(); foreach ($options as $option => $value) { if (isset($value)) { ini_set("session.{$option}", $value); } } self::$_started = session_start(); if (!self::$_started) { return false; } self::$data =& $_SESSION; // prevent proxy-jumping and session hijacks $ip = self::read('Security.remoteAddr'); if ($ip && env('REMOTE_ADDR') != $ip) { session_write_close(); session_regenerate_id(true); self::$_started = session_start(); } if (empty($ip)) { self::write('Security.remoteAddr', env('REMOTE_ADDR')); } } return self::$_started; }
public function oauth() { if (isset($this->params['url']['code'])) { $code = $this->params['url']['code']; } SlSession::write('Api.facebook.accessToken', r('access_token=', '', $this->Facebook->graph("oauth/access_token", array('client_id' => SlConfigure::read('Api.facebook.appId'), 'redirect_uri' => Sl::url(true), 'client_secret' => SlConfigure::read('Api.facebook.secret'), 'code' => $code, 'decode' => false)))); $this->redirect(SlConfigure::read('Api.facebook.oauthSuccess')); }
function parse($html = null, $blockName = 'document', $blockParams = null) { $blockParams = (array) $blockParams; $blockParams += array('range' => true, 'min' => 0, 'max' => 100, 'values' => array(0, 100), 'domId' => SL::uniqid()); $options = $blockParams; unset($options['domId']); $key = "jqueryUiSlider-{$blockParams['domId']}"; SlConfigure::write("Asset.js.ready.{$key}", "\$('#{$blockParams['domId']}').slider(" . json_encode($options) . ')'); return parent::parse($html, $blockName); }
public function admin_index($activeSection = null) { $this->set('sections', $sections = SlConfigure::read2("Config.sections")); foreach ($sections as $section => $settings) { if (!SlAuth::isAuthorized('config' . Inflector::camelize($section))) { unset($sections[$i]); } } if (isset($this->data['_section'])) { $activeSection = $this->data['_section']; } if (empty($activeSection) || !isset($sections[$activeSection])) { $activeSection = reset(array_keys($sections)); } $settings = $this->_getSettings($activeSection); $this->set('title', __t(SlConfigure::read2("Config.sections.{$activeSection}"))); if ($this->data) { $locales = SlConfigure::read('I18n.locales'); foreach ($settings as $name => &$setting) { if (is_int($name)) { $name = "setting_{$name}"; } if ($setting['collection'] == 'user') { $setting['collection'] = 'User' . SlAuth::user('id'); } if (empty($setting['translate'])) { if (isset($this->data[$name])) { $value = $this->data[$name]; if (isset($setting['type']) && $setting['type'] == 'json') { $value = json_decode($value, true); } elseif (isset($setting['type']) && $setting['type'] == 'array') { $value = Set::normalize($value, false); } SlConfigure::write($setting['name'], $value, true, $setting['collection']); } } else { foreach ($locales as $locale) { if (isset($this->data["{$name}_{$locale}"])) { $value = $this->data["{$name}_{$locale}"]; if (isset($setting['type']) && $setting['type'] == 'json') { $value = json_decode($value, true); } elseif (isset($setting['type']) && $setting['type'] == 'array') { $value = Set::normalize($value, false); } SlConfigure::write($setting['name'], $value, true, "{$setting['collection']}.{$locale}"); } } } } $settings = $this->_getSettings($activeSection); $this->Session->setFlash(__t('Configuration saved'), array('class' => 'success')); } $this->data['_section'] = $activeSection; $this->set('settings', $settings); }
function parse($html = null, $blockName = 'document', $blockParams = null) { $blockParams = (array) $blockParams; if (empty($html)) { $html = '.blend'; } $blockParams += array(); $options = $blockParams ? json_encode($blockParams) : ''; $key = "blend_" . Inflector::slug($html); SlConfigure::write("Asset.js.footer.blend", 'blend/jquery.blend-min'); SlConfigure::write("Asset.js.ready.{$key}", "\$('{$html}').blend({$options});"); }
function parse($html = null, $blockName = 'document', $blockParams = null, $noCycle = false) { $messages = SlConfigure::read2('Message'); if ($messages) { SlSession::delete('Message'); } else { $messages = array(); } $this->vars['bufferedOutput'] = SlConfigure::read('View.bufferedOutput'); SlConfigure::delete('View.bufferedOutput'); if ($messages || $this->vars['bufferedOutput']) { $this->blocks["loop"]->params[0] = $messages; return parent::parse($html, $blockName); } }
function parse($html = null, $blockName = 'document', $blockParams = null) { $blockParams = (array) $blockParams; if (empty($html)) { $html = 'a[rel^="colorbox"]'; } $blockParams += array('skin' => null); if ($blockParams['skin']) { SlConfigure::write("Asset.css.colorbox", "colorbox/{$blockParams['skin']}/colorbox"); } unset($blockParams['skin']); $options = $blockParams ? json_encode($blockParams) : ''; $key = "colorbox_" . Inflector::slug($html); SlConfigure::write("Asset.js.ready.{$key}", "\$('{$html}').colorbox({$options});"); }
/** * Mark a node change, triggering cascade cache clearing * * @param AppModel $model * @param int $id */ public function changed($model, $id = null) { if (empty($id)) { $id = $model->getID(); } if ($model->Behaviors->enabled('Translate')) { $locales = SlConfigure::read('I18n.locales'); foreach ($locales as $locale) { $key = Inflector::underscore($model->alias) . "_{$id}_{$locale}"; Cache::delete($key, 'models'); } } else { $key = Inflector::underscore($model->alias) . "_{$id}"; Cache::delete($key, 'models'); } }
public function getSession($scope = null) { $this->accessToken = SlSession::read('Api.facebook.accessToken'); if ($this->accessToken) { return; } if (is_array($scope)) { $scope = implode(',', $scope); } $appId = SlConfigure::read('Api.facebook.appId'); $redirectUrl = array('plugin' => 'api', 'controller' => 'facebook', 'action' => 'oauth'); if (!empty($this->params['prefix'])) { $redirectUrl += array($this->params['prefix'] => false); } $redirectUrl = urlencode(Sl::url($redirectUrl, true)); $this->controller->redirect("https://graph.facebook.com/oauth/authorize?client_id={$appId}&redirect_uri={$redirectUrl}&scope={$scope}"); }
/** * @param AppController $controller * @return bool */ public function constructClasses($controller) { // load FireCake (see FirePhp) if (!function_exists('firecake') && Configure::read() && strpos(env('HTTP_USER_AGENT'), 'FirePHP') !== false) { App::import('Vendor', 'DebugKit.FireCake'); } // load toolbar if (empty($controller->params['bare']) && SlConfigure::read('Sl.debug.debugKit') && Configure::read()) { // IE6 not supported if (strpos(env('HTTP_USER_AGENT'), 'MSIE 6') === false) { // sometimes needed in Ajax requests by DebugKit // $controller->helpers[] = 'Form'; $controller->components['DebugKit.Toolbar'] = in_array('Interactive', App::objects('plugin')) ? array('panels' => array('Interactive.interactive')) : array(); } } return true; }
/** * Get all data of a node (cached) * * @param int $id * @parsm bool $hit True to increment the hit counter * @return array */ public static function read($id, $options = array()) { if (empty($id)) { $id = self::getModel()->getID(); } $options += array('hit' => false, 'auth' => false); $key = "cms_node_{$id}_" . SlConfigure::read('I18n.locale'); $data = Cache::read($key, 'models'); if (empty($data)) { $data = self::getModel()->readCached($id); } if ($options['hit']) { //... } if ($options['auth']) { //... } return $data; }
public function admin_add() { $newItem = empty($this->data); $this->admin_edit(); if ($newItem && !empty($this->params['named']['cms_node_id'])) { $nodeId = $this->params['named']['cms_node_id']; $node = $this->CmsBlock->CmsNode->read(null, $nodeId); if ($node) { // set link title to node title $locales = SlConfigure::read('I18n.locales'); foreach ($locales as $locale) { $this->data['CmsBlock']['title_' . $locale] = $node["CmsNode"]['short_title_' . $locale] ? $node["CmsNode"]['short_title_' . $locale] : $node["CmsNode"]['title_' . $locale]; } $this->data['CmsBlock']['cms_node_id'] = $nodeId; $this->data['CmsBlock']['url'] = SlNode::url($node, array('base' => false, 'slug' => false, 'lang' => false)); } } $this->render('admin_edit'); }
function parse($html = null, $blockName = 'document', $blockParams = null) { if (empty($html)) { $id = SlConfigure::read('Api.google.analytics.id'); } if (empty($html)) { return; } SlConfigure::write("Asset.js.footer.{$html}", array('weight' => 1000, 'after' => <<<end var _gaq = _gaq || []; _gaq.push(['_setAccount', '{$html}']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); end )); }
public function send($to, $message, $params = array()) { $params += SlConfigure::read('Api.hqSms') + array('encoding' => 'utf-8', 'test' => false, 'details' => false); if (is_array($to)) { $multiple = true; foreach ($to as $i => &$phone) { $phone = $this->standartizePhoneNoMd($phone); if (empty($phone)) { unset($to[$i]); } } $params['to'] = implode(',', $to); } else { $multiple = false; $params['to'] = $this->standartizePhoneNoMd($to); } if (empty($params['to'])) { return; } $protocol = $params['secure'] && SlConfigure::read('Sl.options.sslTransport') ? 'https' : 'http'; unset($params['secure']); if (strlen($params['password']) != 32) { $params['password'] = md5($params['password']); } $params['message'] = $message; App::import('Core', 'HttpSocket'); $socket = new HttpSocket(); Sl::krumo($params); $result = $socket->post("{$protocol}://www.hqsms.com/api/send.do", $params); if ($multiple) { $result = explode(';', $result); foreach ($result as &$item) { $item = explode(':', $item); } return $result; } else { return explode(':', $result); } }
function parse($html = null, $blockName = 'document', $blockParams = null) { // set defaults $blockParams = (array) $blockParams; $blockParams += array('options' => array('fx' => 'backout'), 'menuClass' => 'lavaLampNoImage', 'domId' => Sl::uniqid(), 'recursive' => 0); $this->vars['domId'] = $id = $blockParams['domId']; // load & configure lavalamp $options = $blockParams['options'] ? json_encode($blockParams['options']) : ''; SlConfigure::write('Asset.css.lavalamp', 'lavalamp/lavalamp_test'); SlConfigure::write('Asset.js.footer.lavalamp', 'lavalamp/jquery.lavalamp.min'); SlConfigure::write("Asset.js.ready.{$id}", "\$('#{$id}').lavaLamp({$options});"); // custom fx easing effects if (!in_array($blockParams['options']['fx'], array('swing', 'linear'))) { SlConfigure::write('Asset.js.footer.easing', 'lavalamp/jquery.easing.min'); } unset($blockParams['options']); // construct DOM self::$parseCallStack[] = $this; $html = Pheme::init('Menu')->parse($html, $blockName, $blockParams); array_pop(self::$parseCallStack); return $html; }
/** * * @param AppModel $model */ public function beforeSave($model) { $localizedFields = $model->Behaviors->enabled('Translate') ? $model->Behaviors->Translate->settings[$model->alias] : array(); $fields = $this->settings[$model->alias]; $locales = SlConfigure::read('I18n.locales'); foreach ($fields as $field => $field2) { if (is_int($field)) { $field = $field2; $field2 = "markdown_{$field}"; } if (in_array($field, $localizedFields)) { foreach ($locales as $locale) { if (isset($model->data[$model->alias]["{$field}_{$locale}"])) { $model->data[$model->alias]["{$field2}_{$locale}"] = $this->_markdown($model->data[$model->alias]["{$field}_{$locale}"]); } } } if (isset($model->data[$model->alias][$field])) { $model->data[$model->alias][$field2] = $this->_markdown($model->data[$model->alias][$field]); } } return true; }
function parse($html = null, $blockName = 'document', $blockParams = null) { // set defaults $blockParams = (array) $blockParams; $blockParams += array('type' => 'default', 'supersubs' => array('extraWidth' => 1.5), 'options' => array(), 'menuClass' => 'sf-menu', 'domId' => Sl::uniqid()); $id = $blockParams['domId']; $blockParams['menuClass'] .= " {$id}"; // load & configure supersubs if ($blockParams['supersubs']) { $ssOptions = json_encode($blockParams['supersubs']); $ssKey = "supersubs_{$id}"; SlConfigure::write("Asset.js.footer.supersubs", 'superfish/js/supersubs'); SlConfigure::write("Asset.js.ready.{$ssKey}", "\$('ul.{$id}').supersubs({$ssOptions});"); } // load & configure superfish $sfOptions = $blockParams['options'] ? json_encode($blockParams['options']) : ''; $sfKey = "superfish_{$id}"; SlConfigure::write("Asset.css.superfish", 'superfish/css/superfish'); SlConfigure::write("Asset.js.footer.superfish", 'superfish/js/superfish'); SlConfigure::write("Asset.js.ready.{$sfKey}", "\$('ul.{$id}').superfish({$sfOptions});"); // alternative styles switch ($blockParams['type']) { case 'vertical': $blockParams['menuClass'] .= " sf-vertical"; SlConfigure::write("Asset.css.superfishVertical", 'superfish/js/superfish-vertical'); break; case 'navbar': $blockParams['menuClass'] .= " sf-navbar"; SlConfigure::write("Asset.css.superfishNavbar", 'superfish/js/superfish-navbar'); break; } unset($blockParams['type']); unset($blockParams['supersubs']); unset($blockParams['options']); // construct DOM return Pheme::init('Menu')->parse($html, $blockName, $blockParams); }
<?php /** * Flash embeds support */ SlConfigure::write('Asset.js.ready.oembed', <<<end \$('.sl-oembed').each(function() { var el = \$(this); var url = el.html(); if (url) { var width = \$(this).parent().width(); var apiUrl = 'http://api.embed.ly/v1/api/oembed?url=' + url + '&callback=?&maxwidth=' + width; \$.getJSON(apiUrl, function(json) { var oembed = json.html; if (oembed.indexOf("wmode") < 0) { oembed = oembed.replace("<embed ", "<param name=\\"wmode\\" value=\\"transparent\\"></param><embed "); oembed = oembed.replace("<embed ", "<embed wmode=\\"transparent\\""); } el.addClass('sl-oembedded').removeClass('sl-oembed').html(oembed); }); } else { \$(this).remove(); } }); end ); ?> <div class="sl-oembed">{$url}</div> <?php class JqueryOembedParser extends PhemeParser {
/** * Set the list of active collections * * @param array $collections names * @param bool $setDefault * * @return string Key to be used in restoreColections(...) */ public static function setCollections($collections = array(), $setDefault = true) { if ($setDefault) { if (self::$_collections && SlExtensions::loaded('Auth')) { $user = SlAuth::user(); if (isset($user['id'])) { $groups = SlSession::read('Auth.groups'); $collections["users"] = 200; if ($groups) { foreach ($groups as $i => $group) { $collections["Group{$group['id']}"] = 201 + $i; $collections[$group['name']] = 201 + $i; } } $collections["User{$user['id']}"] = 299; } else { $collections["guest"] = 299; } } $controller = Sl::getInstance()->controller; if ($controller) { $collections["{$controller->name}Controller"] = 50; if (!empty($controller->params['home'])) { $collections['home'] = 70; } if (!empty($controller->params['plugin'])) { $plugin = Inflector::camelize($controller->params['plugin']); $collections["{$plugin}Plugin"] = 60; // $collections["{$plugin}{$controller->name}"] = 61; } } $collections = am(array('important' => 1000, 'cookie' => 10, 'session' => 20, 'global' => 0), $collections); } $collections = Set::normalize($collections); arsort($collections); self::$_collectionsNoLocale = $collections; $localizedCollections = array(); foreach ($collections as $collection => $priority) { if (self::$_locale) { $localizedCollections[] = $collection . "." . self::$_locale; } $localizedCollections[] = $collection; } $key = self::rememberCollections(); self::$_collections = $localizedCollections; self::_refresh(); return $key; }
function assetTimestamp($path) { if (strpos($path, '?') === false && SlConfigure::read('Asset.options.timestamp')) { return $this->assetUrl(preg_replace('/^' . preg_quote($this->webroot, '/') . '/', '', $path)); } return $path; }
public function logout() { SlAuth::logout(); $this->redirect(SlConfigure::read('Auth.url.afterLogout')); }
* Here, we are connecting '/' (base path) to controller called 'Pages', * its action called 'display', and we pass a param to select the view file * to use (in this case, /app/views/pages/home.ctp)... */ // check installation if (Sl::version() != SlConfigure::read('Sl.version')) { if (!preg_match('!/install|/users/login!', Sl::url(false))) { SlConfigure::write('Message.migrate', array('message' => __t('System files have been recently updated. Proceeding to database migration...'), 'params' => array('class' => 'message'))); Router::connect(Sl::url(false), array('controller' => 'install', 'action' => 'migrate')); } } // localized routes $langRules = array('lang' => implode('|', SlConfigure::read('I18n.langs'))); // home $home = SlConfigure::read1('Routing.home'); Router::connect('/', $home); Router::connect('/:lang', $home, $langRules); // prefixed homes $prefixedRoutes = SlConfigure::read('Routing.prefixes'); foreach ($prefixedRoutes as $prefix => $route) { Router::connect("/{$prefix}", $route); } // custom routes $routes = SlConfigure::read('Routing.routes'); foreach ($routes as $expr => $route) { Router::connect($expr, $route); Router::connect("/:lang{$expr}", $route, $langRules); } Router::connect('/:lang/:plugin/:controller/:action/*', array(), $langRules); Router::connect('/:lang/:controller/:action/*', array(), $langRules); Router::parseExtensions();
/** * * @param array $params Parameters for controller * @access public */ function dbConnectionError() { extract(SlConfigure::read('Db.default')); $this->controller->set('title', __t('No database connection to {$params} ({$password})', array('params' => "{$login}@{$host}/{$database}", 'password' => __t($password ? "uses password" : "no password")))); $this->_outputMessage('dbConnectionError'); }
* 'models' => array('/full/path/to/models/', '/next/full/path/to/models/'), * 'views' => array('/full/path/to/views/', '/next/full/path/to/views/'), * 'controllers' => array('/full/path/to/controllers/', '/next/full/path/to/controllers/'), * 'datasources' => array('/full/path/to/datasources/', '/next/full/path/to/datasources/'), * 'behaviors' => array('/full/path/to/behaviors/', '/next/full/path/to/behaviors/'), * 'components' => array('/full/path/to/components/', '/next/full/path/to/components/'), * 'helpers' => array('/full/path/to/helpers/', '/next/full/path/to/helpers/'), * 'vendors' => array('/full/path/to/vendors/', '/next/full/path/to/vendors/'), * 'shells' => array('/full/path/to/shells/', '/next/full/path/to/shells/'), * 'locales' => array('/full/path/to/locale/', '/next/full/path/to/locale/') * )); * */ App::build(array('plugins' => array(APP . 'extensions/'))); /** * As of 1.3, additional rules for the inflector are added below * * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array())); * Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array())); * */ Cache::config('sl', array('engine' => 'File', 'prefix' => 'sl_', 'duration' => Configure::read() ? '+10 seconds' : '+999 days')); Cache::config('models', array('engine' => 'File', 'prefix' => 'sl_', 'path' => CACHE . 'models' . DS, 'duration' => '+7 days')); App::import('lib', 'sl'); App::import('lib', 'sl_configure'); App::import('lib', 'sl_extensions'); App::import('lib', 'sl_session'); App::import('lib', 'sl_cookie'); SlExtensions::trigger('bootstrap'); Configure::write('Routing.prefixes', array_keys(SlConfigure::read('Routing.prefixes')));
/** * Private helper method to create associated models of a given class. * * @param string $assoc Association name * @param string $className Class name * @deprecated $this->$className use $this->$assoc instead. $assoc is the 'key' in the associations array; * examples: var $hasMany = array('Assoc' => array('className' => 'ModelName')); * usage: $this->Assoc->modelMethods(); * * var $hasMany = array('ModelName'); * usage: $this->ModelName->modelMethods(); * @return void * @access private */ function __constructLinkedModel($assoc, $className = null) { if (!SlConfigure::read('Sl.options.lazyLoadModels')) { return parent::__constructLinkedModel($assoc, $className); } if (empty($className)) { $className = $assoc; } $this->_lazyLoaderBusy = true; if (!isset($this->{$assoc}) || $this->{$assoc}->name !== $className) { $model = array('class' => $className, 'alias' => $assoc); $this->_lazyLoadedModels[$assoc] = $model; // <-- the magic starts here } $this->_lazyLoaderBusy = false; }
/** * Loads Components and prepares them for initialization. * Models will be lazy loaded by default * * @return mixed true if models found and instance created, or cakeError if models not found. * @access public * @see Controller::loadModel() * @link http://book.cakephp.org/view/977/Controller-Methods#constructClasses-986 */ function constructClasses() { if (SlExtensions::getInstance()->dependencyError) { $params = SlExtensions::getInstance()->dependencyError; SlExtensions::getInstance()->dependencyError = false; $this->cakeError('missingDependence', $params); } SlExtensions::trigger('constructClasses', $this); $this->__mergeVars(); // Component class sets components by reference, hence triggering an uneeded read operation // Avoid magic __get() method calls by setting null values $this->components = Set::normalize($this->components); foreach ($this->components as $component => $settings) { if (strpos($component, '.') !== false) { list($plugin, $component) = explode('.', $component); } $this->{$component} = null; } if (!SlConfigure::read('Sl.options.lazyLoadModels')) { return parent::constructClasses(); } $this->Component->init($this); if ($this->uses !== null || $this->uses !== array()) { if ($this->uses) { $uses = is_array($this->uses) ? $this->uses : array($this->uses); $modelClassName = $uses[0]; if (strpos($uses[0], '.') !== false) { list($plugin, $modelClassName) = explode('.', $uses[0]); } $this->modelClass = $modelClassName; } } return true; }