I have a Love Factory extension in Joomla.
Love Factory 4.1.1
Joomla version 3.1
I extended interaction so the user can become a fan.
But when the JModelLegacy::getInstance (html.php) tries to get an Instance it crashed on require_once $path in legacy.php.
I tried to change only format in friends model and then it does not load it too.
It just take part of the code from required class and paste it on the screen. Example from friend.php
<?php
//class definition missing
//function definition missing
if (friendsLimitReached()) {
$this->setError(FactoryText::_('membership_restriction_error_friends_limit'));
$this->setState('membership_restriction_error', true);
return false;
}
// Load friendship request.
$table = $this->getTable('Friend');
$result = $table->load(array('sender_id' => $userId, 'receiver_id' => $user->id, 'pending' => 1));
// Check if friendship request was found.
if (!$result) {
$this->setError(FactoryText::_('friend_task_accept_error_request_not_found'));
return false;
}
// Check if it's relationship request and if users already have a relationship.
if (2 == $table->type && $this->usersInRelationship($user->id, $userId)) {
return false;
}
$table->accept();
return true;
}
public function reject($userId) {
// Initialise variables.
$user = JFactory::getUser();
// Load friendship request.
$table = $this->getTable('Friend');
$result = $table->load(array('sender_id' => $userId, 'receiver_id' => $user->id, 'pending' => 1));
// Check if friendship request was found.
if (!$result) {
$this->setError(FactoryText::_('friend_task_accept_error_request_not_found'));
return false;
}
$table->remove();
return true;
}
public function cancel($userId) {
$user = JFactory::getUser();
$table = $this->getTable('Friend');
$return = $table->load(array('sender_id' => $user->id, 'receiver_id' => $userId, 'type' => 1, 'pending' => 1));
// Check if request exists.
if (!$return) {
$this->setError(FactoryText::_('friend_task_cancel_error_request_not_found'));
return false;
}
if (!$table->delete()) {
$this->setError($table->getError());
return false;
}
return true;
}
public function request($userId) {
// Initialise variables.
$user = JFactory::getUser();
// Check friends limit
$model = JModelLegacy::getInstance('Friends', 'FrontendModel');
if ($model->friendsLimitReached()) {
$this->setError($model->getError());
$this->setState('membership_restriction_error', true);
return false;
}
// Check if sending request to self
if ($userId == $user->id) {
$this->setError(FactoryText::_('friend_taks_request_error_self_request'));
return false;
}
// Check if user is blacklisted
$model = JModelLegacy::getInstance('Blacklist', 'FrontendModel');
if ($model->isBlacklisted($user->id, $userId)) {
$this->setError($model->getError());
return false;
}
// Check if user is allowed to interact with members of same gender
$my_profile = $this->getTable('Profile', 'Table');
$profile = $this->getTable('Profile', 'Table');
$my_profile->loadAndMembership($user->id);
$profile->load($userId);
if (!$my_profile->membership_sold->same_gender_interaction && $my_profile->sex == $profile->sex) {
$this->setError(FactoryText::_('membership_restriction_error_same_gender_interaction'));
$this->setState('membership_restriction_error', true);
return false;
}
// Check if request already sent or friends already
$query = ' SELECT id' . ' FROM #__lovefactory_friends' . ' WHERE ((sender_id = ' . $userId . ' AND receiver_id = ' . $user->id . ')' . ' OR (sender_id = ' . $user->id . ' AND receiver_id = ' . $userId . '))' . ' AND type = 1';
$this->_db->setQuery($query);
$result = $this->_db->loadResult();
if ($result) {
$this->setError(FactoryText::_('friend_task_request_error_alredy_friends_or_pending'));
return false;
}
$message = JRequest::getVar('message', '', 'POST', 'string');
$friend = $this->getTable('Friend');
$friend->request($user->id, $userId, $message);
// Send notification
$mailer = FactoryMailer::getInstance();
$mailer->send( 'friend_request', $userId, array( JFactory::getUser($userId)->username, JFactory::getUser($user->id)->username, ) );
return true;
}
public function remove($userId) {
$friendship = $this->getFriendship($userId, 1);
if (!$friendship || 1 == $friendship->pending) {
$this->setError(FactoryText::_('friend task remove friend not found'));
return false;
}
$table = $this->getTable('Friend', 'Table');
$table->bind($friendship);
if (!$table->remove()) {
$this->setError($table->getError());
return false;
}
return true;
}
public function promote($mode, $userId) {
if ('promote' == $mode) {
return $this->promoteFriend($userId);
}
return $this->demoteFriend($userId);
}
public function getFriendshipStatus($firstUser, $secondUser, $type = 1) {
if (!$firstUser || ! $secondUser) {
return 0;
}
$dbo = $this->getDbo();
$query = $dbo->getQuery(true) ->select('f.*') ->from('#__lovefactory_friends f') ->where('((f.sender_id = ' . $dbo->quote($firstUser) . ' AND f.receiver_id = ' . $dbo->quote($secondUser) . ') OR (f.sender_id = ' . $dbo->quote($secondUser) . ' AND f.receiver_id = ' . $dbo->quote($firstUser) . '))') ->where('f.type = ' . $dbo->quote($type));
$result = $dbo->setQuery($query) ->loadObject();
if (!$result) {
return 0;
}
if ($result->pending) {
return $firstUser == $result->sender_id ? 2 : 3;
}
return 1;
}
protected function promoteFriend($userId) {
// Initialise variables.
$friendship = $this->getFriendship($userId);
$user = JFactory::getUser();
// Check if users are friends.
if (!$friendship || $friendship->pending == 1) {
$this->setError(FactoryText::_('friend_task_promote_friend_not_found'));
return false;
}
// Check if user is already a top friend.
if (($friendship->sender_id == $user->id && $friendship->sender_status) || ($friendship->receiver_id == $user->id && $friendship->receiver_status)) {
$this->setError(FactoryText::_('friend task promote already top friend'));
return false;
}
// Check if top friends limit is reached.
$friends = JModelLegacy::getInstance('Friends', 'FrontendModel');
if ($friends->friendsLimitReached(1)) {
$this->setError(FactoryText::_('friend task promote top friends limit reached'));
$this->setState('membership_restriction_error', true);
return false;
}
// Promote friend.
$table = $this->getTable('Friend', 'Table');
$table->id = $friendship->id;
if ($friendship->sender_id == $user->id) {
$table->sender_status = 1;
}
else {
$table->receiver_status = 1;
}
if (!$table->store()) {
$this->setError($table->getError());
return false;
}
return true;
}
protected function demoteFriend($userId) {
// Initialise variables.
$friendship = $this->getFriendship($userId);
$user = JFactory::getUser();
// Check if users are friends.
if (!$friendship || $friendship->pending == 1) {
$this->setError(FactoryText::_('friend_task_promote_friend_not_found'));
return false;
}
// Check if user is top friend.
if (($friendship->sender_id == $user->id && !$friendship->sender_status) || ($friendship->receiver_id == $user->id && !$friendship->receiver_status)) {
$this->setError(FactoryText::_('friend task demote not top friend'));
return false;
}
// Demote friend.
$table = $this->getTable('Friend', 'Table');
$table->id = $friendship->id;
if ($friendship->sender_id == $user->id) {
$table->sender_status = 0;
}
else {
$table->receiver_status = 0;
}
if (!$table->store()) {
$this->setError($table->getError());
return false;
}
return true;
}
public function getFriendship($userId, $type = 1) {
$user = JFactory::getUser();
$dbo = $this->getDbo();
$query = $dbo->getQuery(true) ->select('f.*') ->from('#__lovefactory_friends f') ->where('((f.sender_id = ' . $dbo->quote($userId) . ' AND f.receiver_id = ' . $dbo->quote($user->id) . ') OR (f.sender_id = ' . $dbo->quote($user->id) . ' AND f.receiver_id = ' . $dbo->quote($userId) . '))') ->where('f.type = ' . $dbo->quote($type));
$result = $dbo->setQuery($query) ->loadObject();
return $result;
}
public function usersInRelationship($receiverId, $senderId) {
$dbo = $this->getDbo();
$users = array($dbo->quote($receiverId), $dbo->quote($senderId));
$query = $dbo->getQuery(true) ->select('f.id, f.sender_id, f.receiver_id') ->from('#__lovefactory_friends f') ->where('(f.sender_id IN ('.implode(',', $users).') OR f.receiver_id IN ('.implode(',', $users).'))') ->where('f.type = ' . $dbo->quote(2)) ->where('f.pending = ' . $dbo->quote(0));
$result = $dbo->setQuery($query) ->loadObject();
if ($result) {
if ($receiverId == $result->sender_id || $receiverId == $result->receiver_id) {
$this->setError(FactoryText::_('friend_task_accept_error_you_already_are_in_a_relationship'));
}
else {
$this->setError(FactoryText::_('friend_task_accept_error_requesting_user_already_is_in_a_relationship'));
}
return true;
}
return false;
}
Is there any special way how the file must be written? Or did anyone else had the same problem?
The problem was caused by the line endings.
NetBeans changed the line endings and then the server was not able with function require_once load the content correctly.
Solution was download a plugin to NetBeans that allows to change line endings.
Related
I am trying to update an old vBulletin product and it keeps throwing an error for me.
Cannot use object of type mysqli_result as array in C:\wamp\www\mem_payment.php on line 124
Line 124:
$vbma->setCustomerNumber(unserialize($purchase['info']), $product['pur_group'], false, $userinfo);
Line 102 - 130
$purchase = $vbulletin->db->query_first("SELECT * FROM " . TABLE_PREFIX .
"ma_purchases WHERE id = '" . $id . "'");
$order = unserialize($purchase['order']);
if ($order[0] !== $vbulletin->GPC['business'])
{
$status_code = '503 Service Unavailable';
// Paypal likes to get told its message has been received
if (SAPI_NAME == 'cgi' or SAPI_NAME == 'cgi-fcgi')
{
header('Status: ' . $status_code);
}
else
{
header('HTTP/1.1 ' . $status_code);
}
}
unset($order[0]);
if ($purchase and !in_array($order[1], array('renew', 'upgrade')))
{
$product = $vbulletin->db->query_read("SELECT pur_group FROM " . TABLE_PREFIX .
"ma_products WHERE id = '" . $order[1] . "'");
$userinfo = fetch_userinfo($purchase['userid']);
$vbma->setCustomerNumber(unserialize($purchase['info']), $product['pur_group'], false,
$userinfo);
$rand = rand($vbulletin->options['memarea_numstart'], $vbulletin->options['memarea_numend']);
$licnum = substr(md5($prodid . rand(0, 20000) . $rand . $rand), 0, rand(10, $vbulletin->
options['memarea_custnumleng']));
$licensedm = datamanager_init('License', $vbulletin, ERRTYPE_ARRAY);
$licensedm->setr('userid', $userinfo['userid']);
I have been reading numerous questions regarding this error stating to essentially:
define your query
query your query
then associate the query
IE:
$query = "SELECT 1";
$result = $mysqli->query($query);
$followingdata = $result->fetch_assoc()
Almost all of the answers are along those lines, although I am failing to see where this needs to be done.
I'm not sure if it has anything to do with the function, but I will add that as well:
function setCustomerNumber($ma_info, $usergroup = '', $usevb = true, $userinfo = '')
{
if ($usevb == false)
{
$this->vbulletin->userinfo = &$userinfo;
}
$fcust = $this->fields['custnum'];
$fpass = $this->fields['mpassword'];
$finfo = $this->fields['info'];
$userdm = datamanager_init('User', $this->vbulletin, ERRTYPE_ARRAY);
$userinfo = fetch_userinfo($this->vbulletin->userinfo['userid']);
$userdm->set_existing($userinfo);
if (!$this->vbulletin->userinfo["$fcust"] and !$this->vbulletin->userinfo["$fpass"])
{
$rand = rand($this->vbulletin->options['memarea_numstart'], $this->vbulletin->
options['memarea_numend']);
$num = $this->vbulletin->options['custnum_prefix'] . substr(md5($rand), 0, $this->
vbulletin->options['memarea_custnumleng'] - strlen($this->vbulletin->options['custnum_prefix']));
$userdm->set($fcust, $num);
$pass = substr(md5(time() . $num . $rand . rand(0, 2000)), 0, $this->vbulletin->
options['memarea_custnumleng']);
$userdm->set($fpass, $pass);
$this->sendCustomerInfo($this->vbulletin->userinfo['userid'], $this->vbulletin->
userinfo['username'], $this->vbulletin->userinfo['email'], $num, $pass);
}
if ($usergroup or $usergroup !== '' or $usergroup !== '0')
{
if ($usergroup != $this->vbulletin->userinfo['usergroupid'])
{
$ma_info['oldgroup'] = $this->vbulletin->userinfo['usergroupid'];
$userdm->set('usergroupid', $usergroup);
}
}
if ($ma_info)
{
$ma_info = serialize($ma_info);
$userdm->set($finfo, $ma_info);
}
$userdm->pre_save();
if (count($userdm->errors) == 0)
{
$userdm->save();
return true;
}
else
{
var_dump($userdm->errors);
return false;
}
}
Why am I getting this error? In your answer could you please explain to me what needs to be changed.
query_read returns mysqli_result&, you need convert it to an array first.
$query_result = $vbulletin->db->query_read(...);
$product = $query_result->fetch_assoc();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I decompined this script of ioncube. The encripted script runs totally fine. But when I run the decrypt script the page gives me 500 Http error. The decrypt script is this:
<?php
/
$_X=base64_decode($_X);$_X=strtr($_X,'123456aouie','aouie123456');$_R=ereg_replace('__FILE__',"'".$_F."'",$_X);eval($_R);$_R=0;$_X=0;
?>
<?php
/
?><?php
#author: A S M Abdur Rab [shibly], shibly#divine-it.net
#abstract: Class for authentication.
#abstract: Helpful methods to make the session/cookies handling, login, logout,
timedout, admin/user authentication, redirection and other authentication
related process safe.
PHP versions 4 and 5
#name: Authentication Class.
#category: Class.
#uses:
#version:
#package: divin_framework
#subpackage: divin_framework.libs
/
class AuthComponent extends Component
{
set allowable IP addresses here/
var $allowedIpAddresses = array('127.0.0.1','192.210.144.165',
'::1');
var $productId = '1001';
var $model = '';
var $condition = '';
var $secretSalt = 'dddonteeeventtthinkaaaboutiiit';
var $msgLogout = 'Logout Successfully.';
var $msgLoggedIn = 'Already logged in.';
var $msgNotLoggedIn = 'You are not logged in.';
var $msgInvalidUser = 'Username and/or Password invalid.';
var $msgTooManyAttempts = 'You have exceeded maximum login attempt limit.';
var $loginPage = 'Login';
var $afterLogoutPage = 'Login';
var $logoutPage = 'Logout';
var $homePage = 'index';
var $site = 'DivineIT';
var $fields = array('login', 'password');
var $timeOffset = 180;
var $loginRequired = false;
var $loginController = null;
var $_authSession = null;
var $_authModel = null;
var $_sessionName = null;
var $sessionId = null;
function __construct()
{
global $AUTH;
if(isset($AUTH))
{
$this->loginRequired = true;
foreach($AUTH as $key => $value)
$this->{$key} = $value;
}
if(!empty($this->model))
{
$this->_sessionName = $this->site . '.' . $this->model;
$this->_authSession = &App::loadModel('AuthSession');
$this->_authModel = &App::loadModel($this->model);
}
}
function startup(&$controller)
{
$permitted = false;
foreach($this->allowedIpAddresses as $ipAddress)
{
if($_SERVER['SERVER_ADDR']===$ipAddress)
{
$permitted = true;
break;
}
}
if(!$permitted)
{
header('Location: forbidden.php');
return;
}
if(defined('PREFIX'))
$prefix = PREFIX;
else
$prefix = '';
if($this->_authModel === null || $this->_authSession === null)
{
if($this->loginRequired === true)
{
$controller->redirect($this->loginController, $this->loginPage);
}
return;
}
$count = count($this->fields);
if($prefix.$this->loginPage == Router::$action && isset($controller->data[$this->model]) && (count($controller->data[$this->model]) == $count))
{
max login attempts#start/
$tryInfo = null;
$tryInfo = $this->Session->get('login_attempts');
if(!is_null($tryInfo))
{
$firstImpression = $tryInfo['first_impression'];
$loginAttempts = $tryInfo['login_attempts'];
$lastImpression = strtotime($tryInfo['last_impression']);
$currentTime = strtotime(currentTime());
if(($currentTime - $lastImpression)>$this->loginLockDuration60)
{
$loginAttempts = 1;
}
if(($loginAttempts>$this->maxLoginAttempts)&&($currentTime - $lastImpression)<$this->loginLockDuration60)
{
$controller->setFlash($this->msgTooManyAttempts);
$controller->redirect($this->loginController, $this->loginPage);
return;
}
else
{
$loginAttempts++;
$tryInfo['login_attempts'] = $loginAttempts;
$tryInfo['last_impression']= currentTime();
$this->Session->set('login_attempts', $tryInfo);
}
}
else
{
$tryInfo['login_attempts'] = 1;
$tryInfo['first_impression'] = currentTime();
$tryInfo['last_impression'] = currentTime();
$this->Session->set('login_attempts', $tryInfo);
}
max login attempts#start/
$this->loggedIn = $this->__login($controller->data[$this->model], $this->condition);
if($this->loggedIn)
{
$requestedPage = $this->Session->get('requested_url');
if(!is_null($requestedPage)&&(count($requestedPage)>0))
{
$requestedController = Inflector::underscore($requestedPage['controller']);
$requestedAction = Inflector::underscore($requestedPage['action']);
$requestedParams = $requestedPage['params'];
$requestedMoreAttrs = $requestedPage['more'];
$requestedScript = $requestedPage['script'];
$this->Session->remove('requested_url');
//$controller->redirect($requestedController, $requestedAction,$requestedParams, $requestedMoreAttrs);
$link = $requestedScript . '?action=' . $requestedController . '-' .
$requestedAction . (!empty($requestedParams) ? ('-'.implode('-', $requestedParams)) : '');
if(!empty($requestedMoreAttrs))
{
foreach($requestedMoreAttrs as $key=>$value)
{
$link .= '&'.$key.'='.$value;
}
}
header('location: ' . $link);
}
else
{
$controller->redirect($this->loginController, $this->homePage);
}
return;
}
else
{
$controller->setFlash($this->msgInvalidUser);
$controller->redirect($this->loginController, $this->loginPage);
}
}
else
{
if(Router::$action != $prefix.$this->loginPage)
{
if(Router::$action === $prefix.$this->logoutPage)
{
$this->__logout();
$controller->setFlash($this->msgLogout);
$controller->redirect($this->loginController, $this->afterLogoutPage);
}
else if($this->__checkValidSession() === false)
{
$requestedPage = $this->Session->get('requested_url');
$requestedPage['controller'] = Router::$controller;
$requestedPage['action'] = Router::$originalAction;
$requestedPage['params'] = Router::$params;
$requestedPage['more'] = Router::$more;
$requestedPage['script'] = Router::$script;
$this->Session->set('requested_url', $requestedPage);
$controller->setFlash($this->msgNotLoggedIn);
$controller->redirect($this->loginController, $this->loginPage);
}
else
{
$this->loggedIn = true;
}
}
}
}
function __login($values, $condition)
{
if(method_exists($this->model, 'authenticate'))
{
$userData = $this->_authModel->authenticate($values, $condition);
}
else
{
foreach($this->fields as $field)
{
if($field === 'password')
{
if($this->encryptPassword)
{
$value = &Database::escape($this->password($values[$field]));
}
else
{
$value = &Database::escape($values[$field]);
}
}
else
{
$value = &Database::escape($values[$field]);
}
$condition .= (empty($condition)?'':' AND ') . '`' . $this->model . '`.' .'`'.$field.'` COLLATE latin1_bin = \''.$value."'";
}
$userData = $this->_authModel->find($condition);
}
if($userData != null)
{
/ TODO: if disable /
// $this->Session->regenerate();
$userSessionId = $this->Session->sessionId();
$this->Session->set( $this->_sessionName, $userSessionId );
$userSessionId = sha1($this->_sessionName . $userSessionId . $this->secretSalt);
$userSessionData = array('AuthSession' =>
array('session_id' => $userSessionId,
'login_time' => currentTime(),
'last_impression' => currentTime(),
'ip' => $_SERVER['REMOTE_ADDR'],
'user_id'=> $userData[$this->model][$this->_authModel->primaryKey],
'model'=> $this->model,
'user_data'=>serialize($userData)
)
);
if($this->_authSession->save($userSessionData, false) === true)
{
$this->userData = &$userData;
$this->sessionId = $userSessionId;
$this->Session->remove('login_attempts');
return true;
}
}
return false;
}
function __logout()
{
Remove from session table.
/
$sessionId = sha1($this->_sessionName . $this->Session->get($this->_sessionName) . $this->secretSalt);
$condition = '`session_id` = \'' . $sessionId . '\' AND `model` = \''.$this->model.'\'';
//$condition.= ' AND `ip`=\'' . $_SERVER['REMOTE_ADDR'] .'\'';
$this->_authSession->delete($condition);
Remove all invalid/expired sessions.
/
$sessionDuration = $this->timeOffset 60;
$inactivityInterval = $this->inactivityInterval 60;
$condition = '(UNIX_TIMESTAMP(\'' . currentTime() . '\') - UNIX_TIMESTAMP(last_impression)) > ' . $inactivityInterval;
$this->_authSession->delete($condition);
$condition = '';
$this->Session->destroySession();
}
function __checkValidSession()
{
$sessionId = sha1($this->_sessionName . $this->Session->get($this->_sessionName) . $this->secretSalt);
// check if session available
$sessionDuration = $this->timeOffset 60;
$inactivityInterval = $this->inactivityInterval 60;
$condition = '(UNIX_TIMESTAMP(\'' . currentTime() . '\') - UNIX_TIMESTAMP(last_impression)) > ' . $inactivityInterval;
$this->_authSession->delete($condition);
$condition = '';
$condition = "session_id = '" . $sessionId . "' AND `model`= '{$this->model}'";
//$condition .= ' AND ip=\'' . $_SERVER['REMOTE_ADDR'] . '\'';
$checkValidSession = $this->_authSession->find($condition);
if(count($checkValidSession) === 1)
{
// check if session expired
$timeOut = strtotime($checkValidSession['AuthSession']['login_time']) + $sessionDuration;
$currentTime = strtotime(currentTime());
if($timeOut > $currentTime)
{
// find logged in user
if(method_exists($this->_authModel, 'checkSession'))
{
$userData = &$this->_authModel->checkSession(unserialize($checkValidSession['AuthSession']['user_data']));
}
else
{
$conditions = $this->model . '.' . $this->_authModel->primaryKey.'=' . $checkValidSession['AuthSession']['user_id'];
$userData = & $this->_authModel->find($conditions);
}
if($userData != null)
{
/ TODO: if disable /
$sessionId = sha1($this->_sessionName . $this->Session->get($this->_sessionName) . $this->secretSalt);
$condition = '`session_id` = \'' . $sessionId . '\' AND `model` = \''.$this->model.'\'';
//$condition.= ' AND `ip`=\'' . $_SERVER['REMOTE_ADDR']. '\'';
$data = array();
$data['AuthSession']['last_impression'] = currentTime();
$this->_authSession->update($data, '', $condition);
$this->userData = & $userData;
return true;
}
}
}
$this->_authSession->delete($condition);
$this->Session->destroySession();
return false;
}
function password($password)
{
return sha1($password);
}
function user($field)
{
if(isset($this->userData[$this->model][$field]))
return $this->userData[$this->model][$field];
return null;
}
}
?>
?>
What's wrong in this script that is giving me 500 error?
There are Multiple Errors in the code. Here is the List!
Syntax Error : MultiLine Comments
Line 8 : Unexpected "/" # it Should be /* or */
Line 20: Unexpected "/" # It should be /* or */
Lines 24-39 : You forgot to start the MultiLine Comment!
Line 43 : Again you forgot to Start single Line Comment!
Line 122 : Again you forgot to start and end Single Line comment!
Line 159 : Don't know if you forgot to start comment or bad code!
Line 261 : Again forgot to start and end the comment!
Line 290 and 297 : Forgot to start and end the comment!
Line 291 and 298 : Syntax error! Looks like you wanted to start comment!
Line 339 : Syntax Error In MultiLine Comment! I am tired of writing again! :v
These are just Comment Errors!
There are multiple Variable Definition errors too! There are other Multiple errors! Check the full code once!
I make the login form and the registration in one page, but I have had problems in the registration form that, when my registration is not redirect to the page I wanted, but i have notice "404 The page you are looking for could not be found!", but the data have already been entered into the registration form successfully saved to the database. the data that is included on the registration form that can be used to login!
Login Controller
<?php class Login extends Front {
var $customer;
public function __construct()
{
parent::__construct();
$this->customer = \CI::Login()->customer();
}
public function login($redirect= '')
{
//find out if they're already logged in
if (\CI::Login()->isLoggedIn(false, false))
{
redirect($redirect);
}
\CI::load()->library('form_validation');
\CI::form_validation()->set_rules('email', 'lang:address_email', ['trim','required','valid_email']);
\CI::form_validation()->set_rules('password', 'Password', ['required', ['check_login_callable', function($str){
$email = \CI::input()->post('email');
$password = \CI::input()->post('password');
$remember = \CI::input()->post('remember');
$login = \CI::Login()->loginCustomer($email, sha1($password), $remember);
if(!$login)
{
\CI::form_validation()->set_message('check_login_callable', lang('login_failed'));
return false;
}
}]]);
if (\CI::form_validation()->run() == FALSE)
{
$this->view('login', ['redirect'=>$redirect, 'loginErrors'=>\CI::form_validation()->get_error_array()]);
}
else
{
redirect($redirect);
}
}
public function logout()
{
\CI::Login()->logoutCustomer();
redirect('login');
}
public function forgotPassword()
{
$data['page_title'] = lang('forgot_password');
\CI::form_validation()->set_rules('email', 'lang:address_email', ['trim', 'required', 'valid_email',
['email_callable', function($str)
{
$reset = \CI::Customers()->reset_password($str);
if(!$reset)
{
\CI::form_validation()->set_message('email_callable', lang('error_no_account_record'));
return FALSE;
}
else
{
//user does exist. and the password is reset.
return TRUE;
}
}
]
]);
if (\CI::form_validation()->run() == FALSE)
{
$this->view('forgot_password', $data);
}
else
{
\CI::session()->set_flashdata('message', lang('message_new_password'));
redirect('login');
}
}
public function register()
{
$redirect = \CI::Login()->isLoggedIn(false, false);
//if they are logged in, we send them back to the my_account by default
if ($redirect)
{
redirect('my-account');
}
\CI::load()->library('form_validation');
//default values are empty if the customer is new
$data = [
'company' => '',
'firstname' => '',
'lastname' => '',
'email' => '',
'phone' => '',
'address1' => '',
'address2' => '',
'city' => '',
'state' => '',
'zip' => '',
'redirect' => \CI::session()->flashdata('redirect')
];
\CI::form_validation()->set_rules('company', 'lang:account_company', 'trim|max_length[128]');
\CI::form_validation()->set_rules('firstname', 'lang:account_firstname', 'trim|required|max_length[32]');
\CI::form_validation()->set_rules('lastname', 'lang:account_lastname', 'trim|required|max_length[32]');
\CI::form_validation()->set_rules('email', 'lang:account_email', ['trim','required','valid_email','max_length[128]', ['check_email_callable', function($str){
return $this->check_email($str);
}]]);
\CI::form_validation()->set_rules('phone', 'lang:account_phone', 'trim|required|max_length[32]');
\CI::form_validation()->set_rules('email_subscribe', 'lang:email_subscribe', 'trim|numeric|max_length[1]');
\CI::form_validation()->set_rules('password', 'lang:account_password', 'required|min_length[6]');
\CI::form_validation()->set_rules('confirm', 'lang:account_confirm', 'required|matches[password]');
if (\CI::form_validation()->run() == FALSE)
{
//if they have submitted the form already and it has returned with errors, reset the redirect
if (\CI::input()->post('submitted'))
{
$data['redirect'] = \CI::input()->post('redirect');
}
// load other page content
//\CI::load()->model('banner_model');
\CI::load()->helper('directory');
$data['registrationErrors'] = \CI::form_validation()->get_error_array();
$this->view('login', $data);
}
else
{
$save['id'] = false;
$save['firstname'] = \CI::input()->post('firstname');
$save['lastname'] = \CI::input()->post('lastname');
$save['email'] = \CI::input()->post('email');
$save['phone'] = \CI::input()->post('phone');
$save['company'] = \CI::input()->post('company');
$save['active'] = (bool)config_item('new_customer_status');
$save['email_subscribe'] = intval((bool)\CI::input()->post('email_subscribe'));
$save['password'] = sha1(\CI::input()->post('password'));
$redirect = \CI::input()->post('redirect');
//if we don't have a value for redirect
if ($redirect == '')
{
$redirect = 'my-account';
}
// save the customer info and get their new id
\CI::Customers()->save($save);
//send the registration email
\GoCart\Emails::registration($save);
//load twig for this language string
$loader = new \Twig_Loader_String();
$twig = new \Twig_Environment($loader);
//if they're automatically activated log them in and send them where they need to go
if($save['active'])
{
\CI::session()->set_flashdata('message', $twig->render( lang('registration_thanks'), $save) );
//lets automatically log them in
\CI::Login()->loginCustomer($save['email'], $save['password']);
//to redirect them, if there is no redirect, the it should redirect to the homepage.
redirect($redirect);
}
else
{
//redirect to the login page if they need to wait for activation
\CI::session()->set_flashdata('message', $twig->render( lang('registration_awaiting_activation'), $save) );
redirect('login');
}
}
}
public function check_email($str)
{
$email = \CI::Customers()->check_email($str);
if ($email)
{
\CI::form_validation()->set_message('check_email_callable', lang('error_email'));
return FALSE;
}
else
{
return TRUE;
}
}}
Login Models
<?php Class Login extends CI_Model{
public function __construct()
{
$customer = CI::session()->userdata('customer');
if(empty($customer))
{
//If we don't have a customer, check for a cookie.
if(isset($_COOKIE['GoCartCustomer']))
{
//the cookie is there, lets log the customer back in.
$info = $this->aes256Decrypt(base64_decode($_COOKIE['GoCartCustomer']));
$cred = json_decode($info);
if(is_object($cred))
{
$this->loginCustomer($cred->email, $cred->password, true);
if( ! $this->isLoggedIn() )
{
// cookie data isn't letting us login.
$this->logoutCustomer();
$this->createGuest();
}
}
}
else
{
//cookie is empty
$this->logoutCustomer();
$this->createGuest();
}
}
}
public function customer()
{
return CI::session()->userdata('customer');
}
public function logoutCustomer()
{
CI::session()->unset_userdata('customer');
//force expire the cookie
$this->generateCookie('[]', time()-3600);
}
private function generateCookie($data, $expire)
{
setcookie('GoCartCustomer', $data, $expire, '/', $_SERVER['HTTP_HOST'], config_item('ssl_support'), true);
}
public function loginCustomer($email, $password, $remember=false)
{
$customer = CI::db()->where('is_guest', 0)->
where('email', $email)->
where('active', 1)->
where('password', $password)->
limit(1)->
get('customers')->row();
if ($customer && !(bool)$customer->is_guest)
{
// Set up any group discount
if($customer->group_id != 0)
{
$group = CI::Customers()->get_group($customer->group_id);
if($group) // group might not exist
{
$customer->group = $group;
}
}
if($remember)
{
$loginCred = json_encode(array('email'=>$customer->email, 'password'=>$customer->password));
$loginCred = base64_encode($this->aes256Encrypt($loginCred));
//remember the user for 6 months
$this->generateCookie($loginCred, strtotime('+6 months'));
}
//combine cart items
if($this->customer())
{
$oldCustomer = $this->customer();
CI::session()->set_userdata('customer', $customer);
\GC::combineCart($oldCustomer); // send the logged-in customer data
}
return true;
}
else
{
return false;
}
}
public function isLoggedIn($redirect = false, $default_redirect = 'login')
{
//$redirect allows us to choose where a customer will get redirected to after they login
//$default_redirect points is to the login page, if you do not want this, you can set it to false and then redirect wherever you wish.
$customer = CI::session()->userdata('customer');
if(!$customer)
{
return false;
}
if($customer->is_guest == 1)
{
if($redirect)
{
redirect($default_redirect);
}
else
{
return false;
}
}
else
{
return true;
}
}
private function createGuest()
{
//create a temp customer
$customerID = CI::Customers()->createGuest();
$customer = CI::db()->where('id', $customerID)->get('customers')->row();
CI::session()->set_userdata('customer', $customer);
}
private function aes256Encrypt($data)
{
$key = config_item('encryption_key');
if(32 !== strlen($key))
{
$key = hash('SHA256', $key, true);
}
$padding = 16 - (strlen($data) % 16);
$data .= str_repeat(chr($padding), $padding);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
}
private function aes256Decrypt($data)
{
$key = config_item('encryption_key');
if(32 !== strlen($key))
{
$key = hash('SHA256', $key, true);
}
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));
$padding = ord($data[strlen($data) - 1]);
return substr($data, 0, -$padding);
}}
Redirect Function
if ( ! function_exists('redirect')){
function redirect($uri = '', $method = 'auto', $code = NULL)
{
if ( ! preg_match('#^(\w+:)?//#i', $uri))
{
$uri = site_url($uri);
}
// IIS environment likely? Use 'refresh' for better compatibility
if ($method === 'auto' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== FALSE)
{
$method = 'refresh';
}
elseif ($method !== 'refresh' && (empty($code) OR ! is_numeric($code)))
{
if (isset($_SERVER['SERVER_PROTOCOL'], $_SERVER['REQUEST_METHOD']) && $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1')
{
$code = ($_SERVER['REQUEST_METHOD'] !== 'GET')
? 303 // reference: http://en.wikipedia.org/wiki/Post/Redirect/Get
: 307;
}
else
{
$code = 302;
}
}
switch ($method)
{
case 'refresh':
header('Refresh:0;url='.$uri);
break;
default:
header('Location: '.$uri, TRUE, $code);
break;
}
exit;
}}
bootstrap.php
$match = $router->match();
// call a closure
if( $match && is_callable( $match['target'] ) ) {
call_user_func_array( $match['target'], $match['params'] );
}
// parse a string and call it
elseif($match && is_string($match['target']))
{
$target = explode('#', $match['target']);
try {
$class = new $target[0];
call_user_func_array([$class, $target[1]], $match['params']);
} catch(Exception $e) {
var_dump($e);
throw_404();
}
}
// throw a 404 error
else
{
throw_404();
}
MyAccount.php
<?php class MyAccount extends Front {
var $customer;
public function __construct()
{
parent::__construct();
\CI::load()->model(array('Locations'));
$this->customer = \CI::Login()->customer();
}
public function index($offset=0)
{
//make sure they're logged in
\CI::Login()->isLoggedIn('my-account');
$data['customer'] = (array)\CI::Customers()->get_customer($this->customer->id);
$data['addresses'] = \CI::Customers()->get_address_list($this->customer->id);
$data['customer_addresses'] = \CI::Customers()->get_address_list($this->customer->id);
// load other page content
//\CI::load()->model('banner_model');
\CI::load()->helper('directory');
\CI::load()->helper('date');
// paginate the orders
\CI::load()->library('pagination');
$config['base_url'] = site_url('my_account');
$config['total_rows'] = \CI::Orders()->countCustomerOrders($this->customer->id);
$config['per_page'] = '15';
$config['first_link'] = 'First';
$config['first_tag_open'] = '<li>';
$config['first_tag_close'] = '</li>';
$config['last_link'] = 'Last';
$config['last_tag_open'] = '<li>';
$config['last_tag_close'] = '</li>';
$config['full_tag_open'] = '<div class="pagination"><ul>';
$config['full_tag_close'] = '</ul></div>';
$config['cur_tag_open'] = '<li class="active"><a href="#">';
$config['cur_tag_close'] = '</a></li>';
$config['num_tag_open'] = '<li>';
$config['num_tag_close'] = '</li>';
$config['prev_link'] = '«';
$config['prev_tag_open'] = '<li>';
$config['prev_tag_close'] = '</li>';
$config['next_link'] = '»';
$config['next_tag_open'] = '<li>';
$config['next_tag_close'] = '</li>';
\CI::pagination()->initialize($config);
$data['orders_pagination'] = \CI::pagination()->create_links();
$data['orders'] = \CI::Orders()->getCustomerOrders($this->customer->id, $offset);
//print_r($offset);
\CI::load()->library('form_validation');
\CI::form_validation()->set_rules('company', 'lang:address_company', 'trim|max_length[128]');
\CI::form_validation()->set_rules('firstname', 'lang:address_firstname', 'trim|required|max_length[32]');
\CI::form_validation()->set_rules('lastname', 'lang:address_lastname', 'trim|required|max_length[32]');
\CI::form_validation()->set_rules('email', 'lang:address_email', ['trim','required','valid_email','max_length[128]', ['check_email_callable', function($str){
return $this->check_email($str);
}]]);
\CI::form_validation()->set_rules('phone', 'lang:address_phone', 'trim|required|max_length[32]');
\CI::form_validation()->set_rules('email_subscribe', 'lang:account_newsletter_subscribe', 'trim|numeric|max_length[1]');
if(\CI::input()->post('password') != '' || \CI::input()->post('confirm') != '')
{
\CI::form_validation()->set_rules('password', 'Password', 'required|min_length[6]|sha1');
\CI::form_validation()->set_rules('confirm', 'Confirm Password', 'required|matches[password]');
}
else
{
\CI::form_validation()->set_rules('password', 'Password');
\CI::form_validation()->set_rules('confirm', 'Confirm Password');
}
if (\CI::form_validation()->run() == FALSE)
{
$this->view('my_account', $data);
}
else
{
$customer = [];
$customer['id'] = $this->customer->id;
$customer['company'] = \CI::input()->post('company');
$customer['firstname'] = \CI::input()->post('firstname');
$customer['lastname'] = \CI::input()->post('lastname');
$customer['email'] = \CI::input()->post('email');
$customer['phone'] = \CI::input()->post('phone');
$customer['email_subscribe'] = intval((bool)\CI::input()->post('email_subscribe'));
if(\CI::input()->post('password') != '')
{
$customer['password'] = \CI::input()->post('password');
}
\GC::save_customer($this->customer);
\CI::Customers()->save($customer);
\CI::session()->set_flashdata('message', lang('message_account_updated'));
redirect('my-account');
}
}
public function check_email($str)
{
if(!empty($this->customer->id))
{
$email = \CI::Customers()->check_email($str, $this->customer->id);
}
else
{
$email = \CI::Customers()->check_email($str);
}
if ($email)
{
\CI::form_validation()->set_message('check_email_callable', lang('error_email'));
return FALSE;
}
else
{
return TRUE;
}
}
public function download($link)
{
$filedata = \CI::DigitalProducts()->get_file_info_by_link($link);
// missing file (bad link)
if(!$filedata)
{
show_404();
}
// validate download counter
if($filedata->max_downloads > 0)
{
if(intval($filedata->downloads) >= intval($filedata->max_downloads))
{
show_404();
}
}
// increment downloads counter
\CI::DigitalProducts()->touch_download($link);
// Deliver file
\CI::load()->helper('download');
force_download('uploads/digital_uploads/', $filedata->filename);
}}
I have created a Database Abstraction Layer over PDO to refrain from creating multiple queries around my scripts which would be pretty hard to maintain.
My DBAL is not very broad; It takes care of simple tasks such as INSERTING, UPDATING and SELECTING (with or without joining). It does not cover more advanced stuff such as selecting from multiple tables etc.
The problem that raised with my DBAL is that it is confusing queries when there are more of the same type in one HTTP request. For example there are three select statements in my script, the first one works, the other two don't. I tried creating a flush method to clear the previously filled attributes by the query, but it's not working and I'm out of ideas. I'm not ready to get rid of my class and get back to writing queries all over - it's so easy to write them this way.
Anyway, this is how I do some queries with my class:
$insert_update_select = array(
'COLUMNS' => array(
'column_name1' => 'data_to_update_or_insert1',
'column_name2' => 'data_to_update_or_insert2'
),
'WHERE' => array('x > y', 'y < x'),
'ORDER' => array('ASC' => 'column_name1'),
'LIMIT' => array(0, 5),
);
// This query works with updating, inserting and selecting
$db = new db();
$db->insert('table_name', $insert_update_select);
$db->update('table_name', $insert_update_select);
$db->select('table_name', $insert_update_select);
Don't ask me how to join tables; I actually forgot how my own syntax works for that, haha. (Gotta try to remember)
Anyway, here is my class:
<?php
class db
{
private $db_type = 'mysql';
private $db_host = 'localhost';
private $db_user = 'root';
private $db_pass = '';
private $db_name = 'imgzer';
private $db;
private $db_connection = '';
private $insert_data = '';
private $update_data = '';
private $select_data = '';
private $condition_data = '';
private $order_data = '';
private $limit_data = '';
private $join_data = array();
private $query;
private $table;
private $return_data;
private $affected_rows;
private $return_id;
// Database tables
const USERS_TABLE = 'imgzer_users';
const CONFIG_TABLE = 'imgzer_config';
public function __construct()
{
$this->db_connection = "$this->db_type:host=$this->db_host;dbname=$this->db_name";
$this->db = new PDO($this->db_connection, $this->db_user, $this->db_pass);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
unset($this->db_pass);
}
public function open()
{
if ($this->db)
{
return true;
}
return false;
}
public function close()
{
if ($this->db->close())
{
return true;
}
return false;
}
private function build_array($type, $data, $join_data = array())
{
if (empty($data))
{
return;
}
$type = strtoupper($type);
$this->update_data = '';
$this->select_data = '';
$data_index = 0;
$data_length = sizeof($data);
$last_row = $data_length - 1;
switch ($type)
{
case 'INSERT':
if (!is_array($data))
{
return;
}
$this->insert_data = '(';
foreach ($data as $column => $value)
{
$this->insert_data .= $column . (($data_index != $last_row) ? ', ' : '');
$data_index++;
}
$data_index = 0;
$this->insert_data .= ') ';
$this->insert_data .= 'VALUES (';
foreach ($data as $column => $value)
{
$this->insert_data .= '?' . (($data_index != $last_row) ? ', ' : '');
$data_index++;
}
$this->insert_data .= ') ';
break;
case 'UPDATE':
$this->update_data = '';
foreach ($data as $column => $value)
{
$this->update_data .= $column . ' = ?' . (($data_index != $last_row) ? ', ' : '');
$data_index++;
}
break;
case 'SELECT':
if (empty($join_data))
{
return;
}
if (is_array($join_data))
{
$from_table = array_keys($join_data['FROM']);
$join_table = array_keys($join_data['TABLES']);
$this->select_data = implode(', ', array_flip($data)) . ' FROM ' ;
$this->select_data .= $from_table[0] . ' ' . $join_data['FROM'][$from_table[0]] . ' ';
for ($i = 0; $i < sizeof($this->join_data); $i++)
{
$this->select_data .= $this->get_join_type($join_data['JOIN']). ' ';
$this->select_data .= $join_table[$i] . ' ' . $join_data['TABLES'][$join_table[$i]];
$this->select_data .= $this->join_data[$i];
}
$this->select_data = rtrim($this->select_data, ' ');
}
else
{
if (!isset($data[0]))
{
$data = array_flip($data);
}
$this->select_data = implode(', ', $data) . ' FROM ' . $this->table . ' ';
}
break;
}
}
private function set_join($on)
{
if (empty($on))
{
return;
}
if (is_array($on))
{
for ($i = 0; $i < sizeof($on); $i++)
{
$on[$i] = ' ON (' . implode(' AND ', $on[$i]) . ') ';
}
}
$this->join_data = $on;
}
private function set_order($order)
{
if (empty($order))
{
return;
}
$this->order_data = ' ORDER BY ';
if (is_array($order))
{
$data_index = 0;
$data_size = sizeof($order) - 1;
foreach ($order as $order_type => $column)
{
if ($order_type != 'ASC' && $order_type != 'DESC')
{
throw new Exception('Order type in SQL has to be either ASC or DESC');
return;
}
$this->order_data .= $column . ' ' . $order_type . (($data_index != $data_size) ? ', ' : '');
$data_index++;
}
return;
}
$this->order_data .= $order;
}
private function set_limit($limit)
{
if (empty($limit))
{
return;
}
if (sizeof($limit) > 2)
{
return;
}
if (sizeof($limit) == 1)
{
$limit = array(0, $limit[0]);
}
if (is_array($limit))
{
$limit = implode(', ', $limit);
}
$this->limit_data = " LIMIT {$limit}";
}
private function set_where($condition)
{
if (empty($condition))
{
return;
}
if (is_array($condition))
{
$condition = implode(' AND ', $condition);
}
$this->condition_data = " WHERE $condition";
}
public function in_set($where_ary)
{
$where_str = implode(', ', $where_ary);
$where_str = substr($where_str, 0, -2);
$where_str = 'IN (' . $where_str . ')';
return $where_str;
}
/*
* Example usage:
* $insert_ary = array('col_1' => 'col_data_1', 'col_2' => 'col_data_2');
* $condition_ary = array('col_1 > 5', 'col_2 <> 10');
* $order_ary = array('ASC' => 'col_1', 'DESC' => 'col_2');
* $limit = array($start = 0, $limit = 5);
* $instance->insert('my_table', $insert_ary, $condition_ary, $order_ary, $limit);
*/
public function insert($table, $data, $return_id = false)
{
$data = $this->data_abstract($data);
// Prepare the arrays
$this->build_array('INSERT', $data['COLUMNS']);
$this->set_where($data['WHERE']);
$this->set_order($data['ORDER']);
$this->set_limit($data['LIMIT']);
$sql = 'INSERT INTO ' . $table . ' ';
$sql .= $this->insert_data;
$sql .= $this->condition_data;
$sql .= $this->order_data;
$sql .= $this->limit_data;
$this->query = $this->db->prepare($sql);
$param_index = 1;
foreach ($data['COLUMNS'] as $column => &$value)
{
$this->query->bindParam($param_index, $value);
$param_index++;
}
$this->query->execute();
if ($return_id)
{
$this->return_id = $this->query->last_insert_id();
}
else
{
$this->affected_rows = $this->query->rowCount();
}
}
public function update($table, $data, $return_id = false)
{
$data = $this->data_abstract($data);
// Prepare the arrays
$this->build_array('UPDATE', $data['COLUMNS']);
$this->set_where($data['WHERE']);
$this->set_order($data['ORDER']);
$this->set_limit($data['LIMIT']);
$sql = 'UPDATE ' . $table . ' SET ';
$sql .= $this->update_data;
$sql .= $this->condition_data;
$sql .= $this->order_data;
$sql .= $this->limit_data;
$this->query = $this->db->prepare($sql);
$param_index = 1;
foreach ($data['COLUMNS'] as $column => &$value)
{
$this->query->bindParam($param_index, $value);
$param_index++;
}
$this->query->execute();
if ($return_data)
{
$this->return_id = $this->query->last_insert_id();
}
else
{
$this->affected_rows = $this->query->rowCount();
}
}
/*
* Joining example:
* $join_data = array(
* 'TABLES' => array('table_2' => 't2', 'table_3' => 't3'),
* 'JOIN' => 'LEFT',
* 'ON' => array(
* array('colx > 15', 'coly < 20'),
* array('fieldx > 15', 'fieldy < 20')
* ),
*);
*/
public function select($table, $data, $join = false, $fetch_type = 'assoc')
{
$data = $this->data_abstract($data);
if ($join)
{
if (!is_array($table))
{
throw new Exception('Table has to be associated with a short index');
return;
}
$this->set_join($join['ON']);
$table = array_merge(array('FROM' => $table), $join);
}
// Globalize table name if not joins are used
$this->table = $table;
// Prepare the arrays
$this->build_array('SELECT', $data['COLUMNS'], $table);
$this->set_where($data['WHERE']);
$this->set_order($data['ORDER']);
$this->set_limit($data['LIMIT']);
$sql = 'SELECT ';
$sql .= $this->select_data;
$sql .= $this->condition_data;
$sql .= $this->order_data;
$sql .= $this->limit_data;
$this->query = $this->db->prepare($sql);
$result = $this->query->execute();
$fetch_type = ($fetch_type == 'assoc') ? PDO::FETCH_ASSOC : PDO::FETCH_NUM;
$fetched_data = $this->query->fetchAll($fetch_type);
$data_result = $fetched_data;
if (sizeof($fetched_data) == 1)
{
$data_result = $fetched_data[0];
}
$this->return_data = $data_result;
// Clear the result
//$this->query->closeCursor();
}
public function fetch()
{
return $this->return_data;
}
public function affected_rows()
{
return $this->affected_rows;
}
private function data_abstract($data)
{
$abstract_ary = array('COLUMNS' => '', 'WHERE' => '', 'ORDER' => '', 'LIMIT' => 0);
return array_merge($abstract_ary, $data);
}
private function get_join_type($type)
{
switch ($type)
{
default:
case 'LEFT':
return 'LEFT JOIN';
break;
case 'RIGHT':
return 'RIGHT JOIN';
break;
case 'INNER':
return 'INNER JOIN';
break;
case 'NORMAL':
case 'JOIN':
return 'JOIN';
break;
}
}
private function flush()
{
unset($this->query, $this->insert_data, $this->update_data, $this->select_data);
}
}
$db = new db();
?>
What's wrong with it (could be a lot) and how do I actually make it work efficiently?
Don't make it stateful.
Even without looking at the code I'll tell you what's the problem: get rid of $this->stmt variable.
For some reason, all the DBAL writers have strong inclination to such a variable... introducing state to their class and thus making it unusable.
All the method calls have to be atomic, each performing all the necessary operations and returning all the requested data. While saving nothing in the class variables. As simple as that. In such a rare case when PDOStatement object have to be used further - return this very object, don't save it inside. Otherwise just return the requested data.
I wold also advise to get rid of your whole DBAL, as it's written out of good intentions but I can tell for sure that implementation turns out to be less helpful but it actually makes your code worse in many aspects - readability, flexibility, maintainability. In pursue for the fictional usability, you are saving yourself only a word or two from SQL, but making whole application code unreliable.
You won't listen to me, though. Some experience in maintaining applications is required to see my point.
i've implemeted the Zend_Acl and its seems to be working.my resources are links :
module_name . "::" . controller_name . "::" . action_name;
i've added something in my code that's breaking and it seems that's i'm redirected to the usual error page but that the Acl comes in saying
Fatal error: Uncaught exception 'Zend_Acl_Exception' with message 'Resource 'default::error::error' not found' in F:\work\php\zendworkspace\myproject\library\Zend\Acl.php on line 365
i have added the default::error::error to the resources but the error is still the same.
when i remove the code that's breaking the whole thing works again.
So i would definitely have the same error when something breaks in my code.
I would like to find out how to solve this. thanks for reading and sharing your experience.
Edit:
the code to implement that is kind of long. this is a db driven ACL with doctrine.
i've modified this tutorial to implement mine.i've cut out the myACL class, looks the same as the one in the tutorial, and the ACL plugin is kind of the same.i've registerd it in the application.ini.
// this class build all the roles and resouces and add 2 users to 2 differents roles and so on
class CMS_Util_AddResourcesAndRoles {
private $arrModules = array();
private $arrControllers = array();
public $arrActions = array();
private $arrIgnores = array('.', '..', '.svn');
public function BuildMCAArrays() {
$this->BuildModuleArray();
$this->BuildControllersArray();
$this->BuildActionArray();
return $this;
}
public function CheckData() {
if (count($this->arrModules) < 1)
throw new CMS_Exception_ResourceNotFound("No Modules found ..");
if (count($this->arrControllers) < 1)
throw new CMS_Exception_ResourceNotFound("No Controllers found ..");
if (count($this->arrActions) < 1)
throw new CMS_Exception_ResourceNotFound("No Actions found ..");
}
public function BuildModuleArray() {
$cmsApplicationModules = opendir(APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules');
while (false !== ($cmsFile = readdir($cmsApplicationModules))) {
if (!in_array($cmsFile, $this->arrIgnores)) {
if (is_dir(APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $cmsFile)) {
$this->arrModules[] = $cmsFile;
}
}
}
closedir($cmsApplicationModules);
return $this->arrModules;
}
public function BuildControllersArray() {
if (count($this->arrModules) > 0) {
foreach ($this->arrModules as $strModuleName) {
$cmsControllerFolder = opendir(APPLICATION_PATH . DIRECTORY_SEPARATOR . "modules" . DIRECTORY_SEPARATOR . $strModuleName . DIRECTORY_SEPARATOR . "controllers");
while (false !== ($cmsFile = readdir($cmsControllerFolder))) {
if (!in_array($cmsFile, $this->arrIgnores)) {
if (preg_match('/Controller/', $cmsFile)) {
// if(strtolower(substr($cmsFile, 0, -14)) != "error")
// $this->arrControllers[$strModuleName][] = strtolower(substr($cmsFile, 0, -14));
$this->arrControllers[$strModuleName][] = strtolower (substr($cmsFile, 0, -14));
}
}
}
closedir($cmsControllerFolder);
}
}
return $this->arrControllers;
}
private function BuildActionArray() {
// $arrMethods = array();
if (count($this->arrControllers) > 0) {
foreach ($this->arrControllers as $strModule => $strController) {
foreach ($strController as $strController) {
if ($strModule == "default") {
$strClassName = ucfirst($strController . 'Controller');
} else {
$strClassName = ucfirst($strModule) . '_' . ucfirst($strController . 'Controller');
}
if (!class_exists($strClassName)) {
Zend_Loader::loadFile(APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . $strModule . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . ucfirst($strController) . 'Controller.php');
}
$objReflection = new Zend_Reflection_Class($strClassName);
$arrMethods = $objReflection->getMethods();
foreach ($arrMethods as $arrMethod) {
if (preg_match('/Action/', $arrMethod->name)) {
$this->arrActions[$strModule][$strController][] = substr($arrMethod->name, 0, -6);
// $this->arrActions[$strModule][$strController][] = substr($this->_camelCaseToHyphens($objMethods->name), 0, -6);
}
}
}
}
}
return $this->arrActions;
}
private function _camelCaseToHyphens($string) {
if ($string == 'currentPermissionsAction') {
$found = true;
}
$length = strlen($string);
$convertedString = '';
for ($i = 0; $i < $length; $i++) {
if (ord($string[$i]) > ord('A') && ord($string[$i]) < ord('Z')) {
$convertedString .= '-' . strtolower($string[$i]);
} else {
$convertedString .= $string[$i];
}
}
return strtolower($convertedString);
}
public function WriteResourcesToDb() {
$this->BuildMCAArrays();
$this->CheckData();
$resources = array();
foreach ($this->arrModules as $strModuleName) {
if (array_key_exists($strModuleName, $this->arrControllers)) {
foreach ($this->arrControllers[$strModuleName] as $strControllerName) {
if (array_key_exists($strControllerName, $this->arrActions[$strModuleName])) {
foreach ($this->arrActions[$strModuleName][$strControllerName] as $strActionName) {
$res = new CMS_Model_Resource();
$res->module_name = $strModuleName;
$res->controller_name = $strControllerName;
$res->action_name = $strActionName;
$res->name = $strModuleName . "_" . $strControllerName . "_" . $strActionName;
$resources[] = $res;
$this->PersistResource($resources);
}
}
}
}
}
return $this;
}
private function PersistResource(array $resourceobject) {
try {
$collection = new Doctrine_Collection("CMS_Model_Resource");
foreach ($resourceobject as $resource) {
$collection->add($resource);
}
$collection->save();
} catch (Exception $exc) {
echo $exc->getTraceAsString();
}
}
public function WriteRoleAndUserstoDb(){
$guest = new CMS_Model_Role();
$guest->name = "guest";
$guest->description = "simple user";
$guest->canbedeleted = true;
$member = new CMS_Model_Role();
$member->name = "member";
$member->description = "member with limited privileges,can access member reserved resources";
$member->canbedeleted = true;
$publisher = new CMS_Model_Role();
$publisher->name = "publisher";
$publisher->description = "publisher with publish an unpublished privileges";
$publisher->canbedeleted = true;
$manager = new CMS_Model_Role();
$manager->name = "manager";
$manager->description = "manager with privileges to publish, to unpublish, general manager of the site";
$manager->canbedeleted = true;
$admin = new CMS_Model_Role();
$admin->name = "administrator";
$admin->description = "admin with all privileges";
$admin->canbedeleted = false;
$superadmin = new CMS_Model_Role();
$superadmin->name = "superadmin";
$superadmin->description = "superadmin to rule them all";
$superadmin->canbedeleted = false;
$superadmin->Parents[0] = $admin;
$admin->Parents[0] = $manager;
$manager->Parents[0] = $publisher;
$publisher->Parents[0] = $member;
$member->Parents[0] = $guest;
$adminname = new CMS_Model_User();
$adminname->id = CMS_Util_Common::uuid();
$adminname->first_name = "adminname";
$adminname->last_name = "surname";
$adminname->full_name = "adminname surname";
$adminname->password = "password";
$adminname->email = "mister#somemail.com";
$adminname->is_active = true;
$adminname->is_verified = true;
$adminname->username ="superadmin";
$adminname->Role = $superadmin;
$adminname2 = new CMS_Model_User();
$adminname2->id = CMS_Util_Common::uuid();
$adminname2->first_name = "adminname2";
$adminname2->last_name = "adminsurname";
$adminname2->email="shallom#someemail.fr";
$adminname2->full_name = "adminname2 adminsurname";
$adminname2->password = "adminadmin";
$adminname2->is_active = true;
$adminname2->is_verified = true;
$adminname2->username ="admin";
$adminname2->Role = $admin;
$thepublisher = new CMS_Model_User();
$thepublisher->id = CMS_Util_Common::uuid();
$thepublisher->first_name = "one publisher";
$thepublisher->last_name = "lastname";
$thepublisher->full_name = "something something";
$thepublisher->email = "user#somegmail.com";
$thepublisher->password = "password";
$thepublisher->username = "publisher";
$thepublisher->is_active = true;
$thepublisher->is_verified = true;
$thepublisher->Role = $publisher;
$conn = Doctrine_Manager::getInstance()->getCurrentConnection();
$conn->flush();
return $this;
}
public function AssignResourcesToRoles(){
$guestcollection = new Doctrine_Collection("CMS_Model_RoleResource");
$guestroles = Doctrine_Core::getTable("CMS_Model_Role")->GetRoleByName("guest");
$defautresources = Doctrine_Core::getTable("CMS_Model_Resource")->GetResourceByModule("default");
foreach($defautresources as $resource){
$guestroleresource = new CMS_Model_RoleResource();
$guestroleresource->Role = $guestroles;
$guestroleresource->Resource = $resource;
$guestcollection->add($guestroleresource);
}
$guestcollection->save();
$admincollection = new Doctrine_Collection("CMS_Model_RoleResource");
$adminroles = Doctrine_Core::getTable("CMS_Model_Role")->GetRoleByName("superadmin");
$adminresources = Doctrine_Core::getTable("CMS_Model_Resource")->GetResourceByModule("admin");
foreach($adminresources as $resource){
$adminroleresource = new CMS_Model_RoleResource();
$adminroleresource->Role = $adminroles;
$adminroleresource->Resource = $resource;
$admincollection->add($adminroleresource);
}
$admincollection->save();
return $this;
}
public function SetAclUp(){
$this->WriteResourcesToDb();
$this->WriteRoleAndUserstoDb();
$this->AssignResourcesToRoles();
return $this;
}
}
as you can see i've granted all links under default to role guest meaning guest can see the default::error::error page when there is a problem.
I can also assure you that, when nothing is broken in my code, i can login with the publisher credential and get bounced anytime i'm trying to go to the admin panel.
The most popular error is that you have not added the resource for any instance.