My problem started right after I upgraded PHP to Version 7 and Phalcon to Version 3.
Problem
I m getting blank page, no error messages (Error is turned on), no `500 Internal server' error in console. The site used to work flawlessly before.
I have following controller IndexController.php
<?php
namespace RealEstate\Property\Controllers;
use \Phalcon\Mvc\Controller;
use \Phalcon\Mvc\View;
use RealEstate\Common\Models as CommonModels;
class IndexController extends Controller
{
public function initialize(){
//Code here
}
public function indexAction(){
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->setVar("total_properties", $this->utils->getTotalProperties());
$this->view->pick("index");
echo "HELLO WORLD";
}
}
The index action doesnot render anything, but yes HELLO WORLD is printed, so there seems there is no errors in code above that line.
My bootstrap index.php
<?php
namespace RealEstate;
use \Phalcon\Mvc\Application;
use \Phalcon\DI\FactoryDefault;
use \Phalcon\Loader;
use \Phalcon\Mvc\Router;
use \Phalcon\Mvc\View;
use \Phalcon\Mvc\Dispatcher;
use \Phalcon\Events\Manager as EventManager;
use \Phalcon\Assets\Manager as Assets;
use \Phalcon\Mvc\Url as UrlProvider;
use \Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
use \Phalcon\Flash\Session as FlashSession;
use \Phalcon\Session\Adapter\Files as SessionAdapter;
use \Phalcon\Http\Response\Cookies;
//use \Phalcon\Session\Adapter\Files as Session;
class MyApplication extends Application
{
const DEFAULT_MODULE = "property";
private $prConfig;
/**
* Register the services here to make them general or register in the ModuleDefinition to make them module-specific
*/
protected function _registerServices()
{
try{
$config = include "../apps/config/config.php";
$di = new FactoryDefault();
$loader = new Loader();
/**
* We're a registering a set of directories taken from the configuration file
*/
$loader->registerDirs(
array(
__DIR__ . '/../apps/library/',
__DIR__ . '/../apps/plugins/'
)
);
$loader->registerNamespaces(array(
'RealEstate\Common\Plugins' => '../apps/plugins/',
'RealEstate\Common\Models' => '../apps/common/models/',
'RealEstate\Library\Pagination' => '../apps/library/',
'Facebook' => __DIR__.'/../apps/plugins/FacebookSDK/'
));
$loader->registerClasses(array(
"FacebookLib" => __DIR__.'/../apps/library/FacebookLib.php',
"Facebook" => __DIR__.'/../apps/plugins/FacebookSDK/autoload.php',
"MobileDetect" => __DIR__.'/../apps/library/MobileDetect.php'
));
$loader->register();
$di->set('config', $config, true);
//Register assets like CSS and JS
$di->set("assets",function(){
$assets = new Assets();
$cdnUrl = $this->cdnurl;
//Add CSS to collection. "true" means we're using base url for css path
$assets->collection('css')->addCss($cdnUrl.'assets/css/frontend/combined.css?v=44');
$assets->collection('footer')->addJs($cdnUrl.'assets/js/frontend/combined.js?v=44', false);
return $assets;
});
$this->prConfig = $config;
//register base url
$di->set('baseurl', function() use ($config){
$url = $config->application->baseUri;
return $url;
});
//register CDN url
$di->set('cdnurl', function() use ($config){
$url = $config->application->cdnUri;
return $url;
});
//Module Information
$di->set('appconfig', function() use ($config){
$appconfig = $config->application;
return $appconfig;
});
//Register URL helper
//set base url
$di->set('url', function() use ($config){
$url = new UrlProvider();
$url->setBaseUri($config->application->baseUri);
return $url;
});
//Register dependency for a database connection
$di->setShared('db', function() use ($config){
return new DbAdapter(array(
"host" => $config->database->host,
"username" => $config->database->username,
"password" => $config->database->password,
"dbname" => $config->database->dbname
));
});
//Register and start session
$di->setShared('session', function() {
$session = new SessionAdapter();
$session->start();
return $session;
});
//Register custom library Utilities, so that it is available through out the application
$di->setShared("utils",function(){
return new \Utilities();
});
//Registering a router
$di->set('router', function() use ($config){
$router = new Router(false);
$controller = "index";
/*Backend Routers Configuration Start*/
$modules = $config->modules;
$router->add('/', array(
'module' => 'property',
'namespace' => 'RealEstate\Property\Controllers\\',
'controller' => 'index',
'action' => 'index'
));
$router->add('/:int', array(
'module' => 'property',
'namespace' => 'RealEstate\Property\Controllers\\',
'controller' => 'index',
'action' => 'index',
'params' =>1
));
//other router settings
$router->notFound(array(
'module' => 'errors',
'namespace' => 'RealEstate\Errors\Controllers\\',
'controller' => 'index',
'action' => 'show404'
));
$router->removeExtraSlashes(true); //ignore trailing slash in urls
/*Backend Routers Configuration End*/
return $router;
});
$di->set('partials', function() {
$partials = new View();
$partials->setPartialsDir('../apps/common/views/');
return $partials;
});
$this->setDI($di);
}catch(\Phalcon\Exception $e){
echo get_class($e), ": ", $e->getMessage(), "\n";
echo " File=", $e->getFile(), "\n";
echo " Line=", $e->getLine(), "\n";
echo $e->getTraceAsString();
}
}
public function main()
{
try{
if (!extension_loaded('phalcon')) {
die("Phalcon extension is not installed or enabled. Please check with host");
}
$this->_registerServices();
if($this->prConfig->application->environment=="development" || $_GET["showerrors"]==1){
ini_set("display_errors","On");
error_reporting(E_ALL ^ E_NOTICE);
}
$arraytemp = json_decode(json_encode($this->prConfig->modules), true); //convert Config object to a simple array
//$this->utils->printr($arraytemp,1);
$keys = array_keys($arraytemp);
$array = array();
if(count($keys)>0){
foreach($keys as $module){
$array[$module]["className"] = "RealEstate\\".ucwords($module)."\Module";
$array[$module]["path"] = "../apps/modules/".$module."/Module.php";
}
}else{
die("The entries for modules not found.");
}
$this->registerModules($array);
echo $this->handle()->getContent();
}catch(\Phalcon\Exception $e){
echo get_class($e), ": ", $e->getMessage(), "\n";
echo " File=", $e->getFile(), "\n";
echo " Line=", $e->getLine(), "\n";
echo $e->getTraceAsString();
}
}
}
$application = new MyApplication();
$application->main();
Have followed This Link as well, but with not much help.
UPDATE
No errors on Server's error log
Thanks
I think I solved this issue. The issue was in Module.php, the issue was in method
public function registerServices($di)
{
try{
//Registering the view component
$di->set('view', function() {
$view = new View();
$view->setViewsDir('../apps/modules/'.$this->module_name.'/views/');
return $view;
});
}catch(\Phalcon\Exception $e){
echo get_class($e), ": ", $e->getMessage(), "\n";
echo " File=", $e->getFile(), "\n";
echo " Line=", $e->getLine(), "\n";
echo $e->getTraceAsString();
}
}
Where, $module_name is a property defined in class.
In above code $this->module_name was undefined. so I changed above method to -
public function registerServices($di)
{
$module = $this->module_name;
try{
//Registering the view component
$di->set('view', function() use($module) {
$view = new View();
$view->setViewsDir('../apps/modules/'.$module.'/views/');
return $view;
});
}catch(\Phalcon\Exception $e){
echo get_class($e), ": ", $e->getMessage(), "\n";
echo " File=", $e->getFile(), "\n";
echo " Line=", $e->getLine(), "\n";
echo $e->getTraceAsString();
}
}
I wondered why it was working in previous version of Phalcon
Related
I'm using PHP on IIS, Phalcon framework. I have a login controller which I'm working on (yes, password isn't encrypted yet, but that's later) but I can't seem to get it to work.
I have a form action posting to signin/doSignin. This is a snippet of the SigninController.php:
public function doSigninAction(){
//$this->view->disable();
$user = User::findFirst([
'conditions' => 'email = :email: AND password = :password:'
, 'bind' => [
'email' => $this->request->getPost('email')
, 'password' => $this->request->getPost('password')
]
]);
if ($user){
echo 1;
return;
}
echo 2;
What results when I run this code is a blank page that simply reports:
Call to undefined method or service 'getDI'
Something somewhere is not lined up properly for the internals of phalcon, but I don't know what I need to check. When I change the above code to this, I get a proper rendering of the view, printing 1 for the user:
$user = new User()/*::findFirst([
'conditions' => 'email = :email: AND password = :password:'
, 'bind' => [
'email' => $this->request->getPost('email')
, 'password' => $this->request->getPost('password')
]
]);*/;
if ($user){
echo 1;
return;
}
echo 2;
My bootstrap is the following:
<?php
try {
set_include_path('c:/workspace/GIIAnalytics/app/views');
//Autoloader
$loader = new \Phalcon\Loader();
$loader->registerDirs([
'../app/controllers/'
, '../app/models/'
, '../app/config/'
]);
/** For MSSQL connections */
$loader->registerNamespaces([
"Twm\Db\Adapter\Pdo" => "../app/library/db/adapter/"
, "Twm\Db\Dialect" => "../app/library/db/dialect/"
]);
$loader->register();
//Dependancy Injection
$di = new \Phalcon\DI\FactoryDefault();
//Config
$configFile = __DIR__ . '/../app/config/config.json';
$config = json_decode ( file_get_contents ( $configFile ) );
$di->setShared('config',$config);
//MSSQL Database connection
$di->set("db", function() use ($di) {
//Database info
/** For MSSQL connections */
$mc = $di->getDI()->getShared('config')['db'];
$db = new Twm\Db\Adapter\Pdo\Mssql($mc);
return $db;
});
//View
$di->set('view', function(){
$view = new \Phalcon\Mvc\View();
$view->setViewsDir('../app/views');
/*
$view->registerEngines([
'.volt' => '\Phalcon\Mvc\View\Engine\Volt'
]);
*/
return $view;
});
// Router
$di->set('router',function(){
$router = new \Phalcon\Mvc\Router();
$router->mount(new Routes());
return $router;
});
// Session
$di->setShared('session', function() {
$session = new \Phalcon\Session\Adapter\Files();
$session->start();
return $session;
});
//Flash Data (temp data)
$di->set('flash', function() {
$flash = new \Phalcon\Flash\Session([
'error' => 'alert alert-danger'
, 'success' => 'alert alert-success'
, 'notice' => 'alert alert-info'
, 'warning' => 'alert alert-warning'
]);
return $flash;
});
//Metadata
$di['modelsMetadata'] = function() {
$metaData = new \Phalcon\Mvc\Model\MetaData\Memory([
'lifetime' => 86400
, 'prefix' => 'metaData'
]);
return $metaData;
};
// custom dispatcher overrides the default
$di->set('dispatcher', function() use ($di) {
$eventsManager = $di->getShared('eventsManager');
// Custom ACL class
$permission = new Permission();
// Listen for events from the $permission class
$eventsManager->attach('dispatch', $permission);
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
//Deploy the app
$app = new \Phalcon\Mvc\Application($di);
echo $app->handle()->getContent();
} catch(\Phalcon\Exception $e) {
echo $e->getmessage();
}
?>
How do I fix the dependency problem?
Found the issue. Phalcon is not good about giving you the line for invalid function calls. It was in my db constructor, where I'm doing $di->getDI this got changed (along with the config reader) to this snippet:
//MSSQL Database connection
$di->set("db", function() use ($di) {
//Database info
/** For MSSQL connections */
$mc = (array) $di->getShared('config')->db;
$db = new Twm\Db\Adapter\Pdo\Mssql($mc);
return $db;
});
I'm currently using Phalcon 3.3 / PHP 7.2 (Ubuntu 18.04 LTS / Windows 10)
I created a custom SecurityPlugin file to verify user permission to access routes. I've defined my roles, resources and permission using Phalcon's ACL.
Here's my SecurityPlugin class
<?php
use Phalcon\Acl;
use Phalcon\Acl\Resource;
use Phalcon\Acl\Role;
use Phalcon\Events\Event;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Acl\Adapter\Memory as AclList;
/**
* Class SecurityPlugin
*
* This is the security plugin that makes sure users access the modules they are assigned to
*
*/
class SecurityPlugin extends Plugin
{
private function _getAcl()
{
if(!isset($this -> persistent -> acl))
{
$acl = new AclList();
$acl -> setDefaultAction(Acl::DENY);
//Add Roles
$roles = [
'base_acc' => new Role(
'BaseAcc',
'This role represents the standard users that are allowed on the platform'
),
'guest' => new Role(
'Guest',
'This is the default role assigned to users that are not logged in'
)
];
//Register Roles
foreach ($roles as $role) {
$acl -> addRole($role);
}
//Add Standard User Resources
$standardResources = [
'store' => ['index']
];
//Add Public Resources
$publicResources = [
'index' => ['index'],
'auth' => ['index', 'login', 'logout', 'register', 'confirmEmail', 'continueReg', 'finishReg', 'verifyPasswordToken', 'forgotPassword', 'updatePassword'],
'errors' => ['show404', 'show503', 'errorConfirm']
];
//Register Standard User Resources
foreach ($standardResources as $resource => $actions)
{
$acl -> addResource(new Resource($resource), $actions);
}
//Register Public Resources
foreach ($publicResources as $resource => $actions)
{
$acl -> addResource(new Resource($resource), $actions);
}
//Register Public Resources to all roles
foreach ($roles as $role) {
foreach ($publicResources as $resource => $actions){
foreach($actions as $action){
$acl -> allow($role -> getName(), $resource, $action);
}
}
}
//Register Standard Resources to standard User Role
foreach ($standardResources as $resource => $actions){
foreach($actions as $action){
$acl -> allow('BaseAcc', $resource, $action);
}
}
$this -> persistent -> acl = $acl;
}
return $this -> persistent -> acl;
}
public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher)
{
$auth = $this->session->get('auth');
if (!$auth){
$role = 'Guests';
} else {
$role = 'BaseAcc';
}
$controller = $dispatcher->getControllerName();
$action = $dispatcher->getActionName();
$acl = $this->_getAcl();
if (!$acl->isResource($controller)) {
$dispatcher->forward([
'controller' => 'errors',
'action' => 'show404'
]);
return false;
}
$allowed = $acl->isAllowed($role, $controller, $action);
if (!$allowed) {
$dispatcher->forward([
'controller' => 'errors',
'action' => 'show401'
]);
//$this->session->destroy();
return false;
}
//Checks thr current user role
//$roles = [];
/*$auth = $this -> session -> get('auth');
if(!$auth)
{
$role = 'Guest';
}
else
{
$role = 'BaseAcc';
}
$acl = $this -> _getAcl();
$controller = $dispatcher -> getControllerName();
$action = $dispatcher -> getActionName();
$lastController = $dispatcher ->getLastController();
if(!$acl -> isResource($controller))
{
$dispatcher -> forward([
'controller' => 'errors',
'action' => 'show404'
]);
return false;
}
if(!$acl -> isAllowed($role, $controller, $action))
{
$dispatcher -> forward([
'controller' => 'errors',
'action' => 'show503'
]);
return false;
}*/
}
}
My part of my application bootstrap:
<?php
define('BASE_PATH', dirname(__DIR__));
define('APP_PATH', BASE_PATH . '/app');
error_reporting(E_ALL);
use Phalcon\Mvc\View as ViewEngine;
use Phalcon\Mvc\Model\MetaData\Files as MetaDataAdapter;
use Phalcon\Mvc\Application as AppEngine;
use Phalcon\Flash\Session as FlashService;
use Phalcon\Flash\Direct as FlashDirect;
use Phalcon\Session\Adapter\Files as SessionHandler;
use Phalcon\Mvc\Url as UrlResolver;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
//use Phalcon\Logger\Adapter\File as LogService;
use Phalcon\Logger\Factory as LogFactory;
try{
//Try our Debugger
// = new Phalcon\Debug();
//$debug -> listen(true, true);
//Application Loader
$loader = new Phalcon\Loader();
//Register Working Directories
$loader -> registerDirs([
APP_PATH . '/controllers',
APP_PATH . '/config',
APP_PATH . '/models',
APP_PATH . '/cache',
APP_PATH . '/plugins',
BASE_PATH . '/vendor',
]);
//Register Namespaces
$loader -> registerNamespaces([
//'AgroTech\Models' => APP_PATH . '/models',
'AgroTech\Plugins' => APP_PATH . '/plugins'
]);
//Register Loader
$loader -> register();
// Use composer autoloader to load vendor classes
require_once BASE_PATH . '/vendor/autoload.php';
$di = new Phalcon\Di\FactoryDefault();
...
$di -> set('dispatcher', function() use ($di){
$eventsManager = $di->getShared('eventsManager');
//Bind our Custom Event Handlers
$eventsManager -> attach('dispatch:beforeExecuteRoute', new SecurityPlugin());
$eventsManager -> attach('dispatch:beforeException', new NotFoundPlugin());
//xdebug_print_function_stack();
$dispatcher = new Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
...
$app = new AppEngine($di);
$response = $app -> handle();
$response -> send();
} catch(Phalcon\Exception $e){
echo "Exception: " . $e -> getMessage();
echo '<pre>' . $e -> getTraceAsString() . '</pre>';
}
However, binding the event 'dispatch:beforeExecuteRoute' with my SecurityPlugin gives me a 503 error. Disabling it makes all my pages acessible. And also, disabling my NotFoundPlugin (which handles invalid routes), I get a Dispatcher Cyclic routing error
Is there something I'm doing wrong?
Note: I based my SecurityPlugin implementation off https://github.com/phalcon/invo
What i can say? Just debug it with xdebug or even var_dumps and that's it? Check what is your $auth, controller, action etc in beforeExecuteRoute method and check what isAllowed is returning and how your acl object looks like after creating it and you will find your mistake easy.
I am facing a strange error. I got a fairly simple piece of code yet it is constantly giving me error that class not found.
The error i am getting is
Fatal error: Class 'pipedriveintegrationConfig' not found in /home/preston/public_html/fullslate-pipedrive/index.php on line 4
Here is index.php
require_once 'config.php';
require_once pipedriveintegrationConfig::PHP_LIB;
require_once 'fullslate.php';
require_once 'pipedrive.php';
require_once 'fullslate-pipedrive.php';
pipedriveintegrationConfig::init();
if ($_SERVER['argc'] > 1) {
$action = $_SERVER['argv'][1];
} else
if (isset($_GET['action'])) {
$action = $_GET['action'];
}
if ($action) {
switch($action) {
case 'sync-clients':
$client = new pipedriveintegrationFullslatePipedrive(pipedriveintegrationFullslateConfig::toArray(), pipedriveintegrationPipedriveConfig::toArray());
$client->syncClients();
break;
default:
throw new CustomException('Unknown command line action: ', $action);
break;
}
} else {
if (file_exists(__DIR__ . '/test.php')) {
require_once __DIR__ . '/test.php';
}
}
Code for config.php is
namespace pipedriveintegration;
class PipedriveConfig{
const URL = 'https://api.pipedrive.com/v1';
const API_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXX';
const STAGE_ID_NEW_PROSPECT = 1;
const STAGE_ID_CONSULTATION_SCHEDULED = 3;
public static
function toArray() {
return array('url' => self::URL, 'api_token' => self::API_TOKEN, 'stage_id_new_prospect' => self::STAGE_ID_NEW_PROSPECT, 'stage_id_consultation_scheduled' => self::STAGE_ID_CONSULTATION_SCHEDULED,);
}
}
class FullslateConfig{
const URL = 'https://slcguitar.fullslate.com/api';
const API_TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXx';
public static
function toArray() {
return array('url' => self::URL, 'api_token' => self::API_TOKEN,);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
class Config{
const PHP_LIB = 'PHPLib.php';
const USE_TIMESTAMP = false;
//'2014-12-15';
public static
function init() {
APP::init(array('mode' => 'development','log' => array('level' => Log::LEVEL_ALL, 'append' => true, 'limit' => 10,), 'curl' => array('log' => false, 'retry' => 3,),'temp' => array('path' => __DIR__, 'active' => true,),));
}
}
class PDEBUG{
const USE_FIDDLER = false;
}
Not sure wrong I am doing?
You need to change the require to:
require_once \pipedriveintegration\Config::PHP_LIB;
Your namespace is pipedriveintegration not pipedriveintegrationConfig. Also the constant is inside the class Config.
I don't know which PHP version are you using but I tested this in 5.6 and it works.
Please remove API tokens, and regenerate them in the application, by publishing API token you are giving access to your account to everyone.
I'm not sure how I should be handling errors within Slim.
I am using a class with functions, e.g. login. When the user enters an incorrect password I'm unsure of how to give them to Slim so that they are able to be displayed to the user.
This is what I currently have:
Route:
$app->post('/submit', function () use ($app) {
$post = (object) $app->request->post();
if($app->user->login($post->log_mail, $post->log_pass)){
$app->setCookie('mail', $post->log_mail, '2 minutes');
$app->redirect('/inbox');
}else{
// redirect
// display errors set by the $app->user->login() function.
}
});
Class function:
public function login($username, $password){
if(!empty($username)){
if(!empty($password)){
if($this->numrows($username, $password)){
// login success
return true;
}else{die('credentials');}
}else{die('password');}
}else{die('username');}
}
How I make use of cookies:
$app = new \Slim\Slim(
[
'debug' => true,
'mode' => 'development',
'cookies.encrypt' => true,
'cookies.secret_key' => 'supersecret',
]);
$app->setCookie('something', 'something' '2 minutes');
Where I am currently using die(), I would like to set an actual error so that the Slim view is able to render it. I looked into Slim's Flash function but so far isn't working.
UPDATE
From the documentation:
If you use the session cookie middleware, you DO NOT need to start a
native PHP session.
Using \Slim\Middleware\SessionCookie, the code will be:
$app = new Slim();
$app->add(new \Slim\Middleware\SessionCookie(array(
'expires' => '20 minutes',
'path' => '/',
'domain' => null,
'secure' => false,
'httponly' => false,
'name' => 'slim_session',
'secret' => 'CHANGE_ME',
'cipher' => MCRYPT_RIJNDAEL_256,
'cipher_mode' => MCRYPT_MODE_CBC
)));
This is my working solution, without using \Slim\Middleware\SessionCookie:
index.php
<?php
require 'vendor/autoload.php';
session_start();
// Twig
$twigView = new \Slim\Views\Twig();
$twigView->parserExtensions = array(
new \Slim\Views\TwigExtension()
);
$app = new \Slim\Slim(
[
'debug' => true,
'mode' => 'development',
'cookies.encrypt' => true,
'cookies.secret_key' => 'supersecret',
'view' => $twigView
]);
$app->setCookie('something', 'something', '2 minutes');
class User {
private function numRows($username, $password){
//Your magic here
return true;
}
public function login($username, $password){
$app = \Slim\Slim::getInstance();
if(!empty($username)){
if(!empty($password)){
if($this->numrows($username, $password)){
// login success
return true;
}else{
$app->flash('error', 'credentials');
}
} else{
$app->flash('error', 'password');
}
} else{
$app->flash('error', 'username');
}
return false;
}
}
//Inject the new user
$app->user = new User();
$app->get('/', function () use ($app){
$flash = $app->view()->getData('flash');
$app->render('form.html');
})->name('Login');
$app->get('/inbox', function () use ($app){
echo "Login OK";
})->name('Inbox');
$app->post('/submit', function () use ($app) {
$post = (object) $app->request->post();
if($app->user->login($post->log_mail, $post->log_pass)){
$app->setCookie('mail', $post->log_mail, '2 minutes');
$app->redirect($app->urlFor('Inbox'));
}else{
// redirect
// display errors set by the $app->user->login() function.
$app->redirect($app->urlFor('Login'));
}
});
$app->run();
form.html
<html>
<head>
<title>Stackoverflow 33192640</title>
</head>
<body>
<form action="./submit" method="POST">
<input type="text" name="log_mail">
<input type="password" name="log_pass">
<button type="submit">Login</button>
</form>
{% if flash.error %}
Error: {{ flash.error }}
{% endif %}
</body>
</html>
OLD ANSWER
Your problem should be connected to the PHP session. You have to set it on top of your file:
session_start();
EDIT:
I misread the question, i think what you are looking for is a simply try catch structure defined your custom exception like this.
class LoginException extends Exception
{
public function __construct($message, $code = 0, Exception $previous = null) {
parent::__construct($message, $code, $previous);
}
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
}
With your code looking like this.
public function login($username, $password){
if(!empty($username)){
if(!empty($password)){
if($this->numrows($username, $password)){
// login success
return true;
}else{ throw new CustomException('Login error', 1);}
}else{throw new CustomException('password error', 2);}
}else{throw new CustomException('username error', 3);}
}
try {
if($app->user->login($post->log_mail, $post->log_pass)){
$app->setCookie('mail', $post->log_mail, '2 minutes');
$app->redirect('/inbox');
}
} catch (CustomException $e) {
// Handle the different codes
}
Here you define an exception, which you give a message and a code, this will represent your different error situation. Know you can handle them differently in the code, and when they occour you just throw the exception with the code which is relevant.
What you are looking for is invoking custom errors, as described on http://docs.slimframework.com/errors/500/.
Raising a custom error would look something like this. Where you could invoke templates with custom errors and so on. There for no need for the if else logic in the submit section.
$app->error(function (\Exception $e) use ($app) {
DoSomethingElse();
$app->render('mycustomerror.php');
});
With the following code, how do I place the on_stats function in one area? So it can be shared and called in all functions on this page instead of copying and pasting the same code over and over again. Also how do I declare $logger just once instead of over and over again.
class API extends Controller
{
public function __construct() {
}
public function api_call1() {
$client = new GuzzleHttp\Client(['defaults' => ['verify' => false]]);
$logger = new Logger('View Logs');
$logger->pushHandler(new StreamHandler(storage_path() . '/logs/api_log.log', Logger::INFO));
$res = $client->get($this->url . "/my/url/", [
'on_stats' => function (TransferStats $stats) use ($logger) {
$logger->info('Request' . $stats->getRequest()->getMethod() .
'Response' . $stats->getResponse()->getStatusCode() .
'Tx Time' . $stats->getTransferTime()
);
}
]);
$response = Response::make($res->getBody(), 200);
$response->header('Content-Type', 'application/json');
return $response;
}
public function api_call2() {
$client = new GuzzleHttp\Client(['defaults' => ['verify' => false]]);
$logger = new Logger('View Logs');
$logger->pushHandler(new StreamHandler(storage_path() . '/logs/api_log.log', Logger::INFO));
$res = $client->get($this->url . "/my/url2/", [
'on_stats' => function (TransferStats $stats) use ($logger) {
$logger->info('Request' . $stats->getRequest()->getMethod() .
'Response' . $stats->getResponse()->getStatusCode() .
'Tx Time' . $stats->getTransferTime()
);
}
]);
$response = Response::make($res->getBody(), 200);
$response->header('Content-Type', 'application/json');
return $response;
}
}
From my viewpoint, it would be a great idea to:
Declare a class property as $logger
Move logger initialization to the constructor
Rewrite the "on_stats" method as a class method, say logEvent(TransferStats $stats) using $this->logger, this way you can avoid using "use" keyword
Pass the client event "on_stats" as a standard PHP callable array:
['on_stats' => [$this, 'logEvent']]