12.23
php
saved
stabb
Note
uses histories, login attempts tables, set to false if not using them
uses histories, login attempts tables, set to false if not using them
- <?php
- /*
- * othAuth By othman ouahbi.
- * comments, bug reports are welcome crazylegs@gmail.com
- * @author CraZyLeGs
- * @version 0.5.0
- * @license MIT
- */
- class othAuthComponent extends Object {
- /**
- * Constants to modify the behaviour of othAuth Component
- */
- // Form vars
- var $user_login_var = 'email';
- var $user_passw_var = 'password';
- var $user_group_var = 'group_id';
- var $user_cookie_var = 'cookie';
- // DB vars
- var $user_table_login = 'email';
- var $user_table_passw = 'password';
- var $user_table_gid = 'group_id';
- var $user_table_active = 'active';
- var $user_table_last_visit = 'last_visit';
- var $auth_url_redirect_var = 'from';
- var $user_model = 'User';
- var $group_model = 'Group';
- var $permission_model = 'Permission';
- var $history_active = true;
- var $history_model = 'UserHistory';
- /*
- * Internals you don't normally need to edit those
- */
- var $controller = true;
- var $gid = 1;
- var $redirect_page;
- var $hashkey = "beijing";
- var $auto_redirect = true;
- var $login_page = '/users/login';
- var $logout_page = '';
- var $access_page = '/users/access_page';
- var $noaccess_page = "/users/login"; // session_flash, flash, back or a page url
- var $mode = 'oth';
- var $pass_crypt_method = 'md5'; // md5, sha1, crypt, crc32,callback
- var $pass_crypt_callback = null; // function name
- var $pass_crypt_callback_file = ''; // file where the function is declared ( in vendors )
- var $cookie_active = true;
- var $cookie_lifetime = '+1 day';
- // asc : the most important group is the group with smallest value
- // desc: the most important group is the group with greatest value
- var $gid_order = 'asc'; // asc desc
- var $strict_gid_check = true;
- var $kill_old_login = true; // when true, form can have another login with the same hash and del the old
- var $error_number = 0;
- var $login_limit = true; // flag to toggle login attempts feature
- var $login_attempts_model = 'LoginAttempts';
- var $login_attempts_num = 3;
- var $login_attempts_timeout = 2; // in minutes
- var $login_locked_out = '+1 day';
- function startup(&$controller)
- {
- //$this->controller = &$controller;
- //pr($controller);
- }
- function _getGidOp()
- {
- if($this->strict_gid_check) return '';
- else return ($this->gid_order == 'desc')? '>=' : '<=';
- }
- function _getHashOf($str)
- {
- switch($this->pass_crypt_method)
- {
- case 'sha1':
- break;
- case 'crypt':
- break;
- case 'callback':
- vendor($this->pass_crypt_callback_file);
- return false;
- break;
- case 'md5':
- default:
- break;
- }
- }
- function init($auth_config = null)
- {
- {
- $this->login_page = $auth_config['login_page'];
- $this->logout_page = $auth_config['logout_page'];
- $this->access_page = $auth_config['access_page'];
- $this->noaccess_page = $auth_config['noaccess_page'];
- else
- $this->noaccess_page = $this->login_page;
- $this->auto_redirect = (boolean) $auth_config['auto_redirect'];
- $this->hashkey = $auth_config['hashkey'];
- $this->strict_gid_check = (boolean) $auth_config['strict_gid_check'];
- $this->mode = $auth_config['mode'];
- {
- $this->allowedAssocUserModels = $auth_config['allowModels']['user'];
- $this->allowedAssocGroupModels = $auth_config['allowModels']['group'];
- {
- $this->allowedAssocPermissionModels = $auth_config['allowModels']['permission'];
- }
- }
- }
- // pass auth data to the view so it can be used by the helper
- $this->_passAuthData();
- }
- function login($ap = 1,$order ='asc') // email,password,group
- {
- if(!$this->_checkLoginAttempts())
- return -3; // too many login attempts
- $params = null;
- $params[$this->user_model] = $this->controller->data[$this->user_model];
- return $this->_login($params);
- }
- function _login($params,$ignore_cookie = false)
- {
- switch ($this->mode)
- {
- case 'oth':
- return $this->othLogin($params,$ignore_cookie);
- break;
- case 'nao':
- return $this->naoLogin($params,$ignore_cookie);
- break;
- case 'acl':
- return $this->aclLogin($params,$ignore_cookie);
- break;
- default:
- return $this->othLogin($params,$ignore_cookie);
- break;
- }
- }
- function othLogin($params,$ignore_cookie=false) // email,password,group
- {
- $params = $params[$this->user_model];
- if($this->Session->valid() && $this->Session->check('othAuth.'.$this->hashkey))
- if(!$this->kill_old_login) return 1;
- return 0;
- uses('sanitize');
- $passw = Sanitize::paranoid($params[$this->user_passw_var]);
- if($login == "" || $passw == "") return -1;
- if(!$ignore_cookie) $passw = $this->_getHashOf($passw);
- $gid_check_op = $this->_getGidOp();//($this->strict_gid_check)?'':'<=';
- {
- $this->gid = (int) Sanitize::paranoid($params[$this->user_group_var]);
- // FIX
- if( $this->gid < 1) $this->gid = 1;
- $conditions[$this->user_model.'.'.$this->user_table_gid] = $gid_check_op.$this->gid;
- }
- $conditions[$this->user_model.'.'.$this->user_table_login] = $login;
- $conditions[$this->user_model.'.'.$this->user_table_passw] = $passw;
- $conditions[$this->user_model.'.'.$this->user_table_active] = 1;
- $UserModel = $this->_createModel();
- $row = $UserModel->find($conditions);
- {
- $this->_saveLoginAttempts();
- return -2;
- }
- else {
- $this->_deleteLoginAttempts();
- $this->_saveCookie($row);
- $this->_saveSession($row);
- // Update the last visit date to now
- {
- }
- // 0.2.5 save history
- if($this->history_active) $this->_addHistory($row);
- if($this->auto_redirect == true)
- {
- $goto = $row[$this->group_model]['redirect'];
- else
- $goto = $this->access_page;
- $back = false;//isset($this->controller->params['url']['url'][$this->auth_url_redirect_var]);
- $this->redirect($goto,$back);
- }
- return 1;
- }
- }
- function naoLogin($params,$ignore_cookie = false) // username,password,group
- {
- $params = $params[$this->user_model];
- if($this->Session->valid() && $this->Session->check('othAuth.'.$this->hashkey))
- {
- if(!$this->kill_old_login)
- {
- return 1;
- }
- }
- if($params == null ||
- {
- return 0;
- }
- uses('sanitize');
- $login = Sanitize::paranoid($params[$this->user_login_var]);
- $passw = Sanitize::paranoid($params[$this->user_passw_var]);
- {
- $this->gid = (int) Sanitize::paranoid($params[$this->user_group_var]);
- if( $this->gid < 1)
- {
- $this->gid = 1;
- }
- }
- if($login == "" || $passw == "")
- {
- return -1;
- }
- if(!$ignore_cookie)
- {
- $passw = $this->_getHashOf($passw);
- }
- "{$this->user_model}.".$this->user_table_login => "$login",
- "{$this->user_model}.".$this->user_table_passw => "$passw",
- "{$this->user_model}.".$this->user_table_active => 1);
- $UserModel =& new $this->user_model;
- $UserModel->recursive = 2;
- $UserModel->{$this->group_model}->unbindAll(array('hasAndBelongsToMany'=>array($this->permission_model)));
- $row = $UserModel->find($conditions);
- $num_users = (int) $UserModel->findCount($conditions);
- foreach ($row[$this->group_model] as $group){
- $gids[] = $group['level'];
- }
- }
- if($this->strict_gid_check)
- {
- }
- else
- {
- $allowed = false;
- switch($this->gid_order)
- {
- case 'asc':
- foreach($gids as $gid)
- {
- if($this->gid >= $gid)
- {
- $allowed = true;
- break;
- }
- }
- break;
- case 'desc':
- foreach($gids as $gid)
- {
- if($this->gid >= $gid)
- {
- $allowed = true;
- break;
- }
- }
- break;
- }
- }
- {
- $this->_saveLoginAttempts();
- return -2;
- }
- else
- {
- $this->_deleteLoginAttempts();
- if(!$ignore_cookie &&
- {
- $this->_saveCookie($row);
- }
- $this->_saveSession($row);
- // Update the last visit date to now
- {
- }
- // 0.2.5 save history
- if($this->history_active)
- {
- $this->_addHistory($row);
- }
- $redirect_page = $this->access_page;
- foreach($row[$this->group_model] as $grp)
- {
- if($grp['level'] == $this->gid)
- {
- {
- $redirect_page = $grp['redirect'];
- }
- }
- }
- $this->redirect($redirect_page);
- return 1;
- }
- }
- // 0.2.5
- function _addHistory(&$row)
- {
- $data[$this->history_model]['username'] = $row[$this->user_model][$this->user_table_login];
- $data[$this->history_model]['fullname'] = $row[$this->user_model]['name'];
- $data[$this->history_model]['groupname'] = $row[$this->group_model]['name'];
- {
- $data[$this->history_model]['visitdate'] = $row[$this->user_model][$this->user_table_last_visit];
- }else
- {
- }
- $HistoryModel =& new $this->history_model;
- $HistoryModel->save($data);
- }
- function _saveSession($row)
- {
- $login = $row[$this->user_model][$this->user_table_login];
- $passw = $row[$this->user_model][$this->user_table_passw];
- $gid = $row[$this->user_model][$this->user_table_gid];
- //$hk = md5($this->hashkey.$login.$passw.$this->gid);
- $hk = $this->_getHashOf($this->hashkey.$login.$passw/*.$gid*/);
- $row["{$this->user_model}"]['login_hash'] = $hk;
- $row["{$this->user_model}"]['hashkey'] = $this->hashkey;
- //$this->Session->write('othAuth.'.$this->gid,$row);
- $this->Session->write('othAuth.'.$this->hashkey,$row);
- }
- // null, true to delete the cookie
- function _saveCookie($row,$del = false)
- {
- if($this->cookie_active)
- {
- if(!$del)
- {
- $login = $row[$this->user_model][$this->user_table_login];
- $passw = $row[$this->user_model][$this->user_table_passw];
- $data = $login.'|'.$passw;
- $data = $this->encrypt($data);
- }else
- {
- }
- }
- }
- function _readCookie()
- {
- // does session exists
- if($this->Session->valid() && $this->Session->check('othAuth.'.$this->hashkey))
- {
- return;
- }
- {
- $str = $_COOKIE['othAuth'];
- {
- }
- $str = $this->decrypt($str);
- //die($passw);
- $data[$this->user_model][$this->user_login_var] = $login;
- $data[$this->user_model][$this->user_passw_var] = $passw;
- $redirect_old = $this->auto_redirect;
- $this->auto_redirect = false;
- $ret = $this->_login($data,true);
- $this->auto_redirect = $redirect_old;
- }
- }
- // delete attempts after a successful login
- function _deleteLoginAttempts()
- {
- if($this->login_limit)
- {
- $ip = env('REMOTE_ADDR');
- $Model = & new $this->login_attempts_model;
- $Model->del($ip);
- if($this->cookie_active)
- }
- }
- function _checkLoginAttempts()
- {
- if($this->login_limit)
- {
- $ip = env('REMOTE_ADDR');
- $Model = & new $this->login_attempts_model;
- // delete all expired and timedout records
- $del_sql = "DELETE FROM {$Model->useTable} WHERE expire <= NOW()";
- if($this->login_attempts_timeout > 0)
- {
- $timeout = $this->login_attempts_timeout * 60;
- $del_sql .= " OR ( UNIX_TIMESTAMP(created) > UNIX_TIMESTAMP(NOW()) - $timeout )";
- }
- $Model->query($del_sql);
- //die("hi!");
- {
- $num = $row[$this->login_attempts_model]['num'];
- $this->login_attempts_current_num = $num;
- if($num >= $this->login_attempts_num)
- {
- return false;
- }
- }else
- {
- $this->login_attempts_current_num = 0;
- }
- {
- $cdata = $_COOKIE['othAuth.login_attempts'];
- {
- }
- $cdata = $this->decrypt($cdata);
- $time = $cdata['t'];
- $num_tries = $cdata['n'];
- if($num_tries >= $this->login_attempts_num)
- {
- return false;
- }
- if($this->login_attempts_current_num == 0 && $num_tries > 0)
- {
- $this->login_attempts_current_num = $num_tries;
- }
- }
- }
- return true;
- }
- function _saveLoginAttempts()
- {
- $num_tries = $this->login_attempts_current_num + 1;
- if($this->login_limit)
- {
- {
- $time = ($keep_for > 0 ? $keep_for : 999999999);
- }
- else
- {
- $keep_for = $this->login_locked_out;
- }
- //die(date("Y-m-d H:i:s",$keep_for));
- $ip = env('REMOTE_ADDR');
- //die(pr($expire));
- $data[$this->login_attempts_model]['ip'] = $ip;
- $data[$this->login_attempts_model]['expire'] = $expire;
- $data[$this->login_attempts_model]['num'] = $num_tries;
- if($num_tries <= 1) // dunno why the model doesn't handle this
- {
- $data[$this->login_attempts_model]['created'] = $expire;
- }
- $Model = & new $this->login_attempts_model;
- $Model->save($data);
- if($this->cookie_active)
- {
- }
- }
- }
- function __notcurrent($page)
- {
- if($page == "") return false;
- uses('inflector');
- $c_a = $this->_handleCakeAdmin($c,$a);
- if($page[0] == '/')
- {
- $c_a = '/'.$c_a;
- }
- //die($c_a.' '.$page);
- // !== is required, $not_current might be boolean(false)
- }
- function redirect($page = "",$back = false)
- {
- if($page == "") $page = $this->logout_page;
- {
- {
- if($back == true)
- {
- $this->Session->write('othAuth.frompage',$this->controller->params['url']['url']);
- $page .= "?".$this->auth_url_redirect_var."=".$this->controller->params['url']['url'];
- }
- else
- {
- if($this->Session->check('othAuth.frompage'))
- {
- $page = $this->Session->read('othAuth.frompage');
- $this->Session->del('othAuth.frompage');
- }
- }
- }
- }
- if($this->__notcurrent($page))
- {
- if($this->__notcurrent($page))
- {
- if ($this->RequestHandler->isAjax())
- {
- $this->RequestHandler->setAjax($this->controller);
- // Brute force !
- echo '<script type="text/javascript">window.location = "'.
- $this->url($page).
- '"</script>';
- exit;
- }
- else
- {
- $this->controller->redirect($page);
- exit;
- }
- }
- }
- }
- // users/login users/logout
- // Logout the user
- function logout ($kill_cookie = false)
- {
- $us = 'othAuth.'.$this->hashkey;
- if($this->Session->valid() && $this->Session->check($us))
- {
- $ses = $this->Session->read($us);
- {
- // two logins of different hashkeys can exist
- if($this->hashkey == $ses[$this->user_model]['hashkey'])
- {
- $this->Session->del($us);
- $this->Session->del('othAuth.frompage');
- /*
- $o = $this->Session->check('othAuth');
- if( is_array( $o ) && empty( $o ))
- {
- $this->Session->del('othAuth');
- }
- */
- if($kill_cookie)
- {
- $this->_saveCookie(null,true);
- }
- if($this->auto_redirect == true)
- {
- // check if logout_page is the action where logout is called!
- {
- $this->redirect($this->logout_page);
- }
- return true;
- }
- }
- }
- }
- return false;
- }
- // Confirms that an existing login is still valid
- function check()
- {
- // is there a restriction list && action is in
- if($this->_validRestrictions())
- {
- // try to read cookie
- $this->_readCookie();
- $us = 'othAuth.'.$this->hashkey;
- // does session exists
- if($this->Session->valid() &&
- $this->Session->check($us))
- {
- $ses = $this->Session->read($us);
- $login = $ses["{$this->user_model}"][$this->user_table_login];
- $password = $ses["{$this->user_model}"][$this->user_table_passw];
- $gid = $ses["{$this->user_model}"][$this->user_table_gid];
- $hk = $ses["{$this->user_model}"]['login_hash'];
- // is user invalid
- if ($this->_getHashOf($this->hashkey.$login.$password/*.$gid*/) != $hk)
- {
- $this->logout();
- return false;
- }
- switch ($this->mode)
- {
- case 'oth':
- $permi = $this->_othCheckPermission($ses);
- break;
- case 'nao':
- $permi = $this->_othCheckPermission($ses,true);
- break;
- case 'acl':
- $permi = $this->_aclCheckPermission($ses);
- break;
- default:
- $permi = $this->_othCheckPermission($ses);
- }
- // check permissions on the current controller/action/p/a/r/a/m/s
- if(!$permi)
- {
- if($this->auto_redirect == true)
- {
- // should probably add $this->noaccess_page too or just flash
- //print_r($this->controller->params);
- $this->redirect($this->noaccess_page,true);
- }
- return false;
- }
- return true;
- }
- if($this->auto_redirect == true)
- {
- $this->redirect($this->login_page,true);
- }
- return false;
- }
- return true;
- }
- function _validRestrictions()
- {
- if($isset)
- {
- $oth_res = $this->controller->othAuthRestrictions;
- {
- if(($oth_res === "*") ||(
- {
- if(
- $this->__notcurrent($this->login_page) &&
- $this->__notcurrent($this->logout_page))
- {
- //die('here');
- return true;
- }
- }
- }
- {
- {
- {
- if($this->isCakeAdminAction())
- {
- if($this->__notcurrent($this->login_page) &&
- $this->__notcurrent($this->logout_page))
- {
- return true;
- }
- }
- }
- }
- foreach($oth_res as $r)
- {
- if($pos === 0)
- {
- return true;
- }
- }
- }
- }
- return false;
- }
- function _othCheckPermission(&$ses,$multi = false)
- {
- //die('c');
- uses('inflector');
- $c_a = $this->_handleCakeAdmin($c,$a);// controller/admin_action -> admin/controller/action
- // extract params
- $c_a_p = $c_a.$params;
- $return = false;
- {
- return false;
- }
- if(!$multi)
- {
- $ses_perms = $ses[$this->group_model][$this->permission_model];
- }else
- {
- foreach ($ses[$this->group_model] as $groups)
- {
- $ses_perms = am($ses_perms, $groups[$this->permission_model]);
- }
- }
- }
- // quickly check if the group has full access (*) or
- // current_controller/* or CAKE_ADMIN/current_controller/*
- // full params check isn't supported atm
- foreach($ses_perms as $sp)
- {
- if($sp['name'] == '*')
- {
- return true;
- }else
- {
- // users/edit/1 users/edit/*
- // users/* users/*
- {
- ($perm_parts[0] == CAKE_ADMIN) &&
- ($perm_parts[1] == $c) &&
- ($perm_parts[2] == "*"))
- {
- return true;
- }
- }
- //else
- //{
- ($perm_parts[0] == $c) &&
- ($perm_parts[1] == "*"))
- {
- return true;
- }
- //}
- }
- }
- {
- $is_checkall = $this->controller->othAuthRestrictions === "*";
- if($is_checkall || $is_cake_admin)
- {
- foreach($ses_perms as $p)
- {
- {
- $return = true;
- break;
- }
- }
- }
- }
- else
- {
- // if current url is restricted, do a strict compare
- // ex if current url action/p and current/p is in the list
- // then the user need to have it in perms
- // current/p/s current/p
- if($a_p_in_array)
- {
- foreach($ses_perms as $p)
- {
- {
- $return = true;
- break;
- }
- }
- }
- // allow a user with permssion on the current action to access deeper levels
- // ex: user access = 'action', allow 'action/p'
- else
- {
- foreach($ses_perms as $p)
- {
- {
- $return = true;
- break;
- }
- }
- }
- }
- return $return;
- }
- function _aclCheckPermission(&$ses)
- {
- //die('c');
- $c = Inflector::underscore($this->controller->name);
- $a = $this->controller->action;
- $aco = "$c:$a";
- $login = $ses["{$this->user_model}"][$this->user_table_login];
- return $this->_aclCheckAccess($login, $aco);
- }
- function _aclCheckAccess($aro_alias, $aco)
- {
- // Check access using the component:
- $access = $this->Acl->check($aro_alias, $aco, $action = "*");
- if ($access === false)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- function _handleCakeAdmin($c,$a)
- {
- {
- if($strpos === 0)
- {
- if($c == null) return $function.'/';
- $c_a = CAKE_ADMIN.'/'.$c.'/'.$function.'/';
- return $c_a;
- }else
- {
- if($c == null) return $a.'/';
- }
- }
- return $c.'/'.$a.'/';
- }
- function getSafeCakeAdminAction()
- {
- {
- $a = $this->controller->action;
- if($strpos === 0)
- {
- return $function;
- }
- }
- return $this->controller->action;
- }
- function isCakeAdminAction()
- {
- {
- $a = $this->controller->action;
- if($strpos === 0)
- {
- return true;
- }
- }
- return false;
- }
- // helper methods
- function user($arg)
- {
- $us = 'othAuth.'.$this->hashkey;
- // does session exists
- if($this->Session->valid() && $this->Session->check($us))
- {
- $ses = $this->Session->read($us);
- {
- return $ses["{$this->user_model}"][$arg];
- }
- else
- {
- return false;
- }
- }
- return false;
- }
- // helper methods
- function group($arg)
- {
- $us = 'othAuth.'.$this->hashkey;
- // does session exists
- if($this->Session->valid() && $this->Session->check($us))
- {
- $ses = $this->Session->read($us);
- {
- return $ses["{$this->group_model}"][$arg];
- }
- else
- {
- return false;
- }
- }
- return false;
- }
- /**
- * Get user's company session value.
- *
- * @return mixed
- * @author Nio Xiao
- **/
- function company($arg)
- {
- $us = 'othAuth_'.$this->hashkey;
- // does session exists
- if($this->Session->valid() && $this->Session->check($us))
- {
- $ses = $this->Session->read($us);
- {
- return $ses['Company'][$arg];
- }
- else
- {
- return false;
- }
- }
- return false;
- }
- // helper methods
- function permission($arg)
- {
- $us = 'othAuth.'.$this->hashkey;
- // does session exists
- if($this->Session->valid() && $this->Session->check($us))
- {
- $ses = $this->Session->read($us);
- {
- {
- {
- $ret[] = $ses[$this->group_model][$this->permission_model][$i][$arg];
- }
- }
- return $ret;
- }
- else
- {
- return false;
- }
- }
- return false;
- }
- function getData($arg = '')
- {
- $us = 'othAuth.'.$this->hashkey;
- // does session exists
- if($this->Session->valid() && $this->Session->check($us))
- {
- $data = $this->Session->read($us);
- {
- return $data;
- }
- return $data;
- }
- return false;
- }
- // passes data to the view to be used by the helper
- function _passAuthData()
- {
- $this->controller->set('othAuth_data',$data);
- }
- function encrypt($string)
- {
- $key = $this->hashkey;
- $result = '';
- for($i=0; $i<strlen($string); $i++) {
- $result.=$char;
- }
- }
- function decrypt($string)
- {
- $key = $this->hashkey;
- $result = '';
- for($i=0; $i<strlen($string); $i++) {
- $result.=$char;
- }
- return $result;
- }
- function getMsg($id)
- {
- switch($id) {
- case 1:
- {
- return "You are already logged in.";
- }break;
- case 0:
- {
- return "Please login!";
- }break;
- case -1:
- {
- return $this->user_login_var."/".$this->user_passw_var." empty";
- }break;
- case -2:
- {
- return "Wrong ".$this->user_login_var."/".$this->user_passw_var;
- }break;
- case -3:
- {
- return "Too many login attempts.";
- }break;
- default:
- {
- return "Invalid error ID";
- }break;
- }
- }
- /*
- * Create the User model to be used in login methods.
- */
- function _createModel()
- {
- // since we don't know if the models have extra associations we need to
- // unbind all the models, and bind only the ones we're interested in
- // mainly for performance ( and security )
- $UserModel =& new $this->user_model;
- $forUser = $this->_mergeModelsToKeep($forUser,$this->allowedAssocUserModels);
- $forGroup = $this->_mergeModelsToKeep($forGroup,$this->allowedAssocGroupModels);
- $forPerm = $this->_mergeModelsToKeep($forPerm,$this->allowedAssocPermissionModels);
- $UserModel->recursive = 2;
- $UserModel->unbindAll($forUser);
- $UserModel->{$this->group_model}->unbindAll($forGroup);
- $UserModel->{$this->group_model}->{$this->permission_model}->unbindAll($forPerm);
- return $UserModel;
- }
- function _mergeModelsToKeep($initial,$toAdd)
- {
- {
- {
- $initial['belongsTo'] =
- am($initial['belongsTo'],$toAdd['belongsTo']);
- }
- {
- $initial['hasMany'] =
- am($initial['hasMany'],$toAdd['hasMany']);
- }
- {
- $initial['hasAndBelongsToMany'] = am($initial['hasAndBelongsToMany'],
- $toAdd['hasAndBelongsToMany']);
- }
- }
- return $initial;
- }
- function url($url = null)
- {
- $base = strip_plugin($this->controller->base, $this->controller->plugin);
- {
- return $this->controller->here;
- }
- elseif ($url{0} == '/')
- {
- $output = $base . $url;
- }
- else
- {
- }
- }
- }
Parsed in 1.997 seconds, using GeSHi 1.0.7.14