Opencart redirect defined routes - php

I'm have couple of not used routes and searching for solutions to redirect this routes.
For example I have ['common/cart','affiliate/edit' ]
array of routes, and where I can add check to check If route is in this array redirect to 404 ? I think that can be done in /controller/common/seo_url.php ?

There are many places where you can add your redirection conditions, the most important thing is avoiding changing the code of core libraries, so I think that the best place would be in index.php
Open the file <OC_ROOT>/index.php
Search for this code fragment:
if (isset($request->get['route'])) {
$action = new Action($request->get['route']);
} else {
$action = new Action('common/home');
}
In the isset part, you can check if the variable $request->get['route'] matches any of your obsolete routes and redirect on that basis, for example:
if (isset($request->get['route'])) {
$ignored_routes = array('common/cart', 'affiliate/edit');
if(in_array($request->get['route'], $ignored_routes))
$action = new Action("error/not_found");
else
$action = new Action($request->get['route']);
} else {
$action = new Action('common/home');
}
P.S: Your assumption is wrong, you can't do it in the file /controller/common/seo_url.php, what you want is <OC_ROOT>/system/engine/action.php ;)

Related

Is using if else statement to load view based on parameters after controller and action part of url efficient or is there a better way of doing this

I can have the following urls
www.example.com/accounts/
www.example.com/accounts/signup
www.example.com/accounts/signup/validate
www.example.com/accounts/login
for each case, accounts becomes my controller, and index, signup, signup and login becomes my actions (or methods) respectively. I have to render different views based on what my actions are. Here is an example of what my code looks like
index
$url_segments = explode('/', $url);
$controller = !empty($url_segments[0]) ? $url_segments[0] : 'home';
array_shift($url_segments); // removes the controller name from array
$action = isset($url_segments[0]) && !empty($url_segments[0]) ? $url_segments[0] : 'index';
array_shift($url_segments); // removes the action name from array
$controller = ucfirst($controller);
$controller = new $controller($url_segments);
$controller->$action();
controller class
class Accounts{
private $url_segments;
public function __construct() {
$this->url_segments = $url_segments;
}
public function index() {
// index code here
}
public function login() {
// login code here
}
public function signup() {
if (!isset($this->url_segments[0])) {
// url entered was: example.com/signup
} else if (isset($this->url_segments[0]) && $this->url_segments[0] == 'validate') {
// url entered was: example.com/signup/validate
}
}
}
from how my code appeared above, it can be seen that as parameters keep adding after the controller and action part of the url I'll need to keep using conditional statements to run the proper code as in the case of /signup/ and signup/validate. Is this method of using conditional statement to load view based on parameters efficient or is there a better way of doing this.
I would recommend you to make use of a routing system like Symfony Routing. There you could add a new Route for every url and redirect them to your specific controller.
Example Route:
$routes = new RouteCollection();
$routes->add('/accounts_signup', route('POST', "/accounts/signup", 'App\Controller\AccountController:signup'));
return $routes;
This route would call the signup method in the AccountController calss when www.example.com/accounts/signup get called with a post request.
I recommend you to use something like this. Even if this might be a bit complicated for the beginning, after reading (and understanding) the docs this will safe you a lot of time and it will make your code more readable as well.

functions in a php router

I have been trying to create a router for my php app,I am kinda new to mvc. I did some research and landed on a tutorial at requiremind.com that helped me do this. How ever there is this line of code that has been making me pull out my hair.
this is my code for the router.
<?php
function call($controller, $action) {
// require the file that matches the controller name
require_once('controllers/' . $controller . '_controller.php');
// create a new instance of the needed controller
switch($controller) {
case 'pages':
$controller = new PagesController();
break;
}
// call the action
$controller->{ $action }();
}
// just a list of the controllers we have and their actions
// we consider those "allowed" values
$controllers = array('pages' => ['home', 'error']);
// check that the requested controller and action are both allowed
// if someone tries to access something else he will be redirected to the error action of the pages controller
if (array_key_exists($controller, $controllers)) {
if (in_array($action, $controllers[$controller])) {
call($controller, $action);
} else {
call('pages', 'error');
}
} else {
call('pages', 'error');
}
?>
this is the part giving me headache $controller->{ $action }();.
The comment says it calls the action . But i do not have a function like action() anywhere.
I know there are different ways of creating a router but I would really want to understand how this particular one works.
I need someone to kindly help me understand what this part of the code does.
Use method_exists func
if(method_exists($controller, $action)) {
$controller->$action();
}
In this particular m-v-c application , looks like the author wanted the function call() to be the main function of the application , you analyze the request then call the function call with the appropriate controller and action. here is usage example of this code,
<?php
$path = trim(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH), "/");
$pathParts = explode("/", $path);
switch ($pathParts[0]){
//www.example.com/home
case "home":
call("homePageController",'showPagefunction');
break;
//www.example.com/contact
case "contact":
if ($_SERVER['REQUEST_METHOD'] == "GET"){
call("contactPageController",'showPageFunction');
}else if($_SERVER['REQUEST_METHOD'] == "POST"){
call("contactPageController",'postContactMsgFunction');
}
break;
default:
header("HTTP/1.0 404 Not Found");
die("404 error");
}
That line calls a method named as specified in the value contained in the variable $action, so for example edit or delete. It is sometimes referred to as variable method call.
This answer was submitted by #arkaschar in the comments section

opencart php program stopped after dispatch()

My opencart front-end works well, while back-end /admin returns me blank page.
I debugged my /admin/index.php and find after
$controller->dispatch($action, new Action('error/not_found'));
the program stopped. So I won't be able to see even the echo.
Here is the code:
Back-end admin/index.php
// Router
if (isset($request->get['route'])) {
$action = new Action($request->get['route']);
} else {
$action = new Action('common/home');
}
// Dispatch
var_dump($action);
$controller->dispatch($action, new Action('error/not_found'));
echo "second+++++++++++++++++++++++++++++++++";
var_dump($response);
// Output
$response->output();
By the way the frond end works well, as it returned me echo and $response value after dispatch:
if (isset($request->get['route'])) {
$action = new Action($request->get['route']);
} else {
$action = new Action($config->get('config_default_controller'));
}
// Dispatch
var_dump($action);
$controller->dispatch($action, new Action($config->get('config_default_controller_error')));
echo "second++++++++++++++++++++++++++";
var_dump($response);
I have checked the $action and $controller they are all with good values and paths.
Do anyone know what happened here with dispatch ? or give me any information about dispatch and why the program stop. Thank you in advance.
after few hours i found solution.
In my case it was wrong config. I had same issue and after checking what is wrong i figure out that my paths in config.php file in admin folder was with wrong values.
Opencart have two cfg files.
Next thing what i changed was config_url in database. Hope it will help you.

Best way to send data from controller to view after a form is submitted?

I'm developing a basic web app using the MVC architecture. I'm building my own to try and fully understand how the MVC arch works so this doubles as a learning exercise.
I am using the Aura Router classes to map my URLs to controllers and action so that something like mysite.com/login will be mapped to LoginController and if I submit a form to mysite.com/login/login it will map it to LoginController->doAction('login').
Example of a controller looks like this:
class LoginController implements iController {
public function doAction( PDO $dbh, $action ) {
switch( $action ) {
case 'login':
//login here
$user = new User();
$user_id = FALSE;
if( $user_id = $user->login( $_POST['email'], $_POST['password'] ) ) {
//save user id to session
}
else {
$results = array( 'errors' => array( 'invalid' ) );
MembershipFunc::redirect( '/login', $results );
}
break;
case 'logout':
//logout
break;
default:
break;
}
}
}
The problem I am facing is that to avoid people from refreshing the page and resubmitting the data I like to forward the user back to the login page if the login failed. Currently if I don't forward them then they would appear on the page mysite.com/login/login and I don't think it's particularly clean. It's okay for my simple login form because an error could redirect to mysite.com/login?error=email,password&email=user#domain.com but in the case of a huge form then I would get a huge URL query which is really gross.
I have scoured for good resources with basic (yet useful) PHP code examples on how MVC works and I've struggled to find anything particularly useful. Should I avoid mapping my URL structures to an action and instead opt for putting a POST field called "action" instead? Should I somehow build a system where I pass this data through an array in the SESSION data?
Any advice?
Note: I would just like to specify that I know this question doesn't fit in the SO culture because it might not have a right/wrong answer but I find SO always has the best/most knowledgeable user-base. If anyone has tips as to where I should direct these questions I would really appreciate it so I don't add clutter!
In my MVC URLs look like:
index.php?c=Controller&m=ControllerMethod&d=slash/sepparated/list/of/stuff
Data (d=) is exploded on the slashes and passed as an array to every controller method.
Autoloading (via spl_autoload_register()) is used to call the class (c=) and then the method in that class (m=).
Also, it sounds like you're either not setting the ACTION on your form or you're deliberately setting the ACTION to GET. As a general rule, ACTION should be POST to keep the URLs sane. Except search forms. Those can be GET with various advantages.
Re-directing to prevent a resubmitted form on refresh is your best option (probably only option). But in my MVC index.php?c=user&m=login handles both the login page and the login action.
Example
class login extends Controller {
public function login($data) {
if(empty($_POST)) {
$this->view = "login.tpl";
return TRUE;
}
$res = $this->model->auth();
if($res !== TRUE) {
$_POST = NULL;
$this->errorState = 1;
$this->errorMsg = "Invalid login details";
$this->login();
return FALSE;
}
Core::setMessage('success', 'user', 'login', '2', 'Logged in successfully');
$home = new home(); //whatever the main controller is
$home->index($data);
//alternatively you can redirect
header("Location: index.php?c=home&m=index);
return TRUE;
}
}
Does this make sense or have I completely missed the mark?

Issuing a redirect from a Joomla module

I am not really familiar with Joomla but I have been tasked with writing a module which functionality is irrelevant to the question.
One of the requirements is that if the module is loaded, it should check if the user is logged in and if not - redirect him into a specific URL.
After some searching I came up with something like this, but it's obviously not a working answer:
$user =& JFactory::getUser();
if (!$user->id) {
include_once JPATH_COMPONENT . DIRECTORY_SEPARATOR . "controller.php"; // assuming com_content
$contentController = new ContentController();
$link = JRoute::_("my url");
$contentController->setRedirect($link);
return;
}
I think the problem lies in getting to the controller. Creating a new controller certainly isn't the way to go. Is there a way to get the current controller from a Joomla module and the issue a redirect?
Thank you for any answers.
i call this static function in each of my controllers construct
static function forceLoggedIn(){
$user = JFactory::getUser();
if($user->guest||$user->id == 0)
{
$error = JText::_('YOU MUST BE LOGGED IN');
//base xkè altrimenti andrebbe in loop di redirect
JFactory::getApplication()->redirect(JURI::base(), $error, 'error' );
return false;
}
}

Categories