So in my application, suppose http://localhost:8888/mvc/user/login this is a URL.
so in this url user is my controller and login is the method in user controller and this is coded in my core files like this:
<?php
/**
*
*/
class Bootstrap
{
function __construct()
{
$url = isset($_GET['url'])?$_GET['url']:null;
$url = rtrim($url,'/');
$url = explode('/', $url);
//print_r($url);
if (empty($url[0])) {
require 'controllers/welcome.php';
$controller = new Welcome();
$controller->index();
return false;
}
$file = 'controllers/'.$url[0].'.php';
if (file_exists($file)) {
require $file;
} else {
$this->showError();
}
$controller = new $url[0];
//calling methods
if (isset($url[2])) {
if (method_exists($controller, $url[2])) {
$controller->{$url[1]}($url[2]);
} else {
$this->showError();
}
} else {
if(isset($url[1])){
if (method_exists($controller, $url[1])) {
$controller->{$url[1]}();
} else {
$this->showError();
}
} else {
$controller->index();
}
}
}
public function showError() {
require 'controllers/CustomError.php';
$controller = new CustomError();
$controller->index();
return false;
}
}
Now my issue is when i try to load css files in views my URL becomes like this:
http://localhost:8888/mvc/public/css/style.css
So now according to above code, it is assuming that public is a controller and CSS is a method. and it is giving an error.
So how can I solve this problem?
I hope you guys understood what is the problem.
Thanks.
try the following for your CSS file in head section of your view:
<link rel="stylesheet" type="text/css" href="http://localhost:8888/mvc/public/css/style.css">
Related
I'm creating a simple PHP MVC system based on the "original" MVC principle, that is...
Controller instructs the model based on user input / queries and loads view
Model is a data layer is is unaware and independant from the controller or view
View creates own copy of data from Model for presentaion purposes
Everything I've done so far conforms to these principles, however, I've stumbled upon a problem as follows...
I set a default page title in the parent model
I inform the model to change its page title value using a model method based on the user page request in the correct controller method (index_controller/index)
I make a copy of models page title in the home view to b used on the template.
The problem is, the page title isnt updated because im setting the view variable in the index view constructor which happens before the model can be updated by the controller.
I can get the correct view variable by fetching and assigning it just before load the template, but the template loading is done in the parent view class which is an issue because different views require different variables.
Please let me know what I'm doing wrong! Any help is much appreciated!
It might help to see some of thecode in question...
lib/bootstrap.php
class Bootstrap {
function __construct() {
// Gets the request URL and seperate into array
$this->url = $this->getUrlArray();
// Generates the controller name based on URL array
$this->controller_name = $this->getControllerName();
// Loads controller file and creates new controller object
$this->controller = $this->getController();
// Calls requested methods based on URL array
$this->callMethods();
}
function getUrlArray() {
$url = isset($_GET['url']) ? rtrim($_GET['url'], '/') : 'index';
$url = explode('/', $url);
return $url;
}
function getControllerName() {
return $this->url[0] . '_controller';
}
function getController() {
$file = 'controllers/' . $this->controller_name . '.php';
if(file_exists($file)) {
require $file;
return new $this->controller_name($this->url[0]);
} else {
require 'controllers/error_controller.php';
return new Error_Controller('error');
}
}
function callMethods() {
if(!isset($this->url[1])) {
$this->controller->index();
} else {
$method_name = $this->url[1];
if(method_exists($this->controller, $method_name)) {
if(!isset($this->url[2])) {
$this->controller->$method_name();
} else {
$this->controller->$method_name($this->url[2]);
}
} else {
$this->controller->index();
}
}
}
}
lib/controller.php
class Controller {
protected $model;
public function __construct($name) {
$this->base_name = $name;
$this->model_name = $this->getModelName();
$this->model = $this->getModel();
$this->view_name = $this->getViewName();
$this->view = $this->getView();
//$this->creatView();
}
public function getModelName() {
return $this->base_name . '_model';
}
public function getViewName() {
return $this->base_name . '_view';
}
public function getModel() {
$file = 'models/' . $this->model_name . '.php';
if(file_exists($file)) {
require $file;
return new $this->model_name();
} else {
die('ERROR: This page is missing a model!');
}
}
public function getView() {
$file = 'views/' . $this->view_name . '.php';
if(file_exists($file)) {
require $file;
return new $this->view_name($this->model);
} else {
die('ERROR: This page is missing a view!');
}
}
}
lib/model.php
class Model {
public function __construct() {
$this->page_title = SITE_NAME;
}
public function setPageTitle($pre, $seperator) {
$this->page_title = $pre . ' ' . $seperator . ' ' . SITE_NAME;
}
}
lib/view.php
class View {
protected $model;
public function __construct(Model $model) {
$this->model = $model;
}
public function output($name, $noInclude = false) {
$file = 'templates/' . $name . '.php';
if(file_exists($file)) {
if($noInclude) {
require 'templates/' . $name . '.php';
} else {
require 'templates/header.php';
require 'templates/' . $name . '.php';
require 'templates/footer.php';
}
} else {
die('ERROR: This page is missing a template!');
}
}
}
controllers/index_controller.php
<?php
class Index_Controller extends Controller {
function __construct($name) {
parent::__construct($name);
}
function index() {
$this->model->setPageTitle('Home', '-');
var_dump($this);
$this->view->output('index/index');
}
function test($value = 'not set') {
echo 'You are in test and the value is ' . $value;
}
}
views/index_view.php
class Index_View extends View {
public function __construct(Model $model) {
parent::__construct($model);
$this->page_title = $this->model->page_title;
}
}
models/index_model.php
class Index_Model extends Model {
public function __construct() {
parent::__construct();
}
}
templates/header.php
<!DOCTYPE html>
<html>
<head>
<title><?php echo $this->page_title; ?></title>
</head>
<body>
<div id="header">
<!-- -->
</div>
<div id="content">
My var_dump in index_controller looks like this...
Cheers,
Tom
I want to display custom image of product on cart page in Magento.
Config.xml file
<checkout>
<rewrite>
<cart_item_renderer>ProductCustomizer_ProductCustomizer_Block_Checkout_Cart_Item_Renderer</cart_item_renderer>
</rewrite>
</checkout>
I have added below code in Block/Checkout/Cart/Item/Renderer.php file
<?php
class ProductCustomizer_ProductCustomizer_Block_Checkout_Cart_Item_Renderer extends Mage_Checkout_Block_Cart_Item_Renderer{
public function getProductThumbnail()
{
$item = $this->_item;
$customize_data = $item->getData('customize_data');
$customize_image = $item->getData('customize_image');
$results_data = $item->getOptionByCode("customizer_data")->getValue();
if(!is_null($results_data)){
$results = unserialize($results_data);
$path = Mage::getBaseDir()."/skin/";
$_product = $item->getProduct()->load();
$customize_image = $this->helper('catalog/image')->init($_product, 'thumbnail',$path.'adminhtml/default/default/images/logo.gif');
//$customize_image = $this->helper('catalog/image')->init($_product, 'thumbnail',$results['image']);
}
if (!empty($customize_image)) {
return $customize_image;
} else {
return parent::getProductThumbnail();
}
}
}
I have tried $customize_image with image "URL", "Path" and "Data (data:image/png;base64,iVBORw0KG....)" but it is not working.
So here is the idea. The init function you are calling is creating the issue for you. Do something like this as you have already done the override of that class.
public function getProductThumbnail1()
{
if (!is_null($this->_productThumbnail)) {
return $this->_productThumbnail;
}
return $this->getSkinUrl('images/jhonson.jpg');
//return $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail');
}
Add this function in that class you have already overridden which is Mage_Checkout_Block_Cart_Item_Renderer. Now in your app/design/frontend/rwd/default/template/checkout/cart/item/default.phtml file or whatever your file is call this function like this echo $this->getProductThumbnail1() rather than this echo $this->getProductThumbnail()->resize(180).
I have found solution. You have override Core class, I have added below class.
Create helper "Customezerimage.php" in Helper in custom module
<?php
class ProductCustomizer_ProductCustomizer_Helper_Customezerimage extends Mage_Catalog_Helper_Image {
public function setCustomeImage($path){
$this->_imageFile = $path;
$this->_setModel(Mage::getModel('productcustomizer/product_image'));
$this->_getModel()->setCustomeBaseFile($this->_imageFile);
return $this;
}
public function __toString() {
try {
$model = $this->_getModel();
$url = $model->getUrl();
} catch (Exception $e) {
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
return $url;
}
}
Create Model "Image.php" in Model/Product directory in custom module.
<?php
class ProductCustomizer_ProductCustomizer_Model_Product_Image extends Mage_Catalog_Model_Product_Image{
public function setCustomeBaseFile($baseFile){
if (!file_exists($baseFile)) {
throw new Exception(Mage::helper('catalog')->__('Image file was not found.'));
}
$this->_newFile = $this->_baseFile = $baseFile;
return $this;
}
public function saveCustomeImage($file = ""){
if(empty($file)){
$file = $this->_newFile;
}
Mage::log($file);
$this->getImageProcessor()->save($file);
return ;
}
public function getUrl(){
$baseDir = Mage::getBaseDir();
$path = str_replace($baseDir . DS, "", $this->_newFile);
return Mage::getBaseUrl() . str_replace(DS, '/', $path);
}
}
Now you can set custom image path that you want to display in cart like below
<?php
class ProductCustomizer_ProductCustomizer_Block_Checkout_Cart_Item_Renderer extends Mage_Checkout_Block_Cart_Item_Renderer{
public function getProductThumbnail()
{
$item = $this->_item;
$customize_data = $item->getData('customize_data');
$customize_image = $item->getData('customize_image');
$results_data = $item->getOptionByCode("customizer_data")->getValue();
if(!is_null($results_data)){
$results = unserialize($results_data);
$imagePathFull = $customize_image;
$_product = $item->getProduct();
$image = $imagePathFull;
return $this
->helper('productcustomizer/customezerimage')
->init($_product, 'thumbnail')->setCustomeImage($image);
}else{
return parent::getProductThumbnail();
}
}
}
I would like to know that if there is a method in the controller which require arguments and the user changes the argument in the URL by hand, and presses enter it should display the default page. Below is my bootstrap, then I have already created a error controller for URL error. So please give some coding guide or if there is some thing in my code, change it. Thanks in advance.
<?php
class App
{
protected $controller = 'indexController';
protected $method = 'index';
protected $params = array();
public function __construct()
{
$url = $this->parseUrl();
//print_r($url);
if (isset($url[0]))
{
if (file_exists('app/controllers/'.$url[0].'.php'))
{
$this->controller = $url[0];
unset($url[0]);
}
require_once('app/controllers/'.$this->controller.'.php');
$this->controller = new $this->controller;
}
else
{
$error = new errorController();
$error->setError("Page Not Found");
echo $error->getError();
}
if (isset($url[1]))
{
if (method_exists($this->controller,$url[1]))
{
$this->method = $url[1];
unset($url[1]);
}
else
{
$error = new errorController();
$error->setError("Page Not Found");
echo $error->getError();
}
}
else
{
$error = new errorController();
$error->setError("Page Not Found");
echo $error->getError();
}
$this->params = $url ? array_values($url) : array();
call_user_func_array(array($this->controller,$this->method),$this->params);
}
public function parseUrl()
{
if (isset($_GET['url']))
{
return $url =explode('/',filter_var(rtrim($_GET['url'],'/'),FILTER_SANITIZE_URL));
}
}
}
The method itself must check if the parameters provided are valid and throw an exception if not. Afterwards just catch the exception and trigger and error page to be displayed.
Seems like you could use POST and $_POST, instead of GET. Then it won't matter if the user includes or alters parameters because your PHP will ignore them.
I'm trying to make a prototype of a simple plugin system I plan on implementing into one of my projects. I have 4 files:
Index.php
Plugins/__BASE.php
Plugins/Sample.php
The index file checks if the 'oncall' method belongs to a class in the Plugins folder using functions I defined in the Plugins class (__BASE.php). If it does exist, it will execute it.
require_once 'Plugins/__BASE.PHP';
$func = 'oncall';
$plugins = new Plugins();
if($plugins->IsPluginMethod($func)) {
$obj = $plugins->GetObject($func);
call_user_func(array($obj, $func));
}
else
echo "'$func' isn't part of a plugin!";
__BASE.php is the base plugin class which all of the plugins will extend. It has two methods: IsPluginMethod() and GetObject(). IsPluginMethod checks if the method name supplied belongs to a class and GetObject returns an instance of the class the method belongs to.
class Plugins {
public $age = "100";
public function IsPluginMethod($func) {
foreach(glob('*.php') as, $file) {
if($file != '__BASE.php') {
require_once $file;
$class = basename($file, '.php');
if(class_exists($class)) {
$obj = new $class;
if(method_exists($obj, $func))
return true;
else
return false;
}
}
}
}
public function GetObject($func) {
foreach(glob('*.php') as $file) {
if($file != '__BASE.php') {
require_once $file;
$class = basename($file, '.php');
if(class_exists($class)) {
$obj = new $class;
return $obj;
}
}
}
}
}
Sample.php is a sample plugin which prints $this->age which is defined in the Plugins class.
class Sample extends Plugins {
public function oncall() {
echo "Age: {$this->age}";
}
}
This is what I see in index.php:
'oncall' isn't part of a plugin!
Can anyone help? Thanks.
In __BASE.php file change (glob('*.php') to glob('Plugins/*.php')
I'm trying to pass multiple parameters in a url that looks like this...
http://somedomain.com/lessons/lessondetails/5/3
... to a function in the controller that looks like this ...
class LessonsController extends Controller
{
public function lessonDetails($studentId, $editRow=NULL)
{
try {
$studentData = new StudentsModel();
$student = $studentData->getStudentById((int)$studentId);
$lessons = $studentData->getLessonsByStudentId((int)$studentId);
if ($lessons)
{
$this->_view->set('lessons', $lessons);
}
else
{
$this->_view->set('noLessons', 'There are no lessons currently scheduled.');
}
$this->_view->set('title', $student['first_name']);
$this->_view->set('student', $student);
return $this->_view->output();
} catch (Exception $e) {
echo "Application error: " . $e->getMessage();
}
}
}
But only the first parameter seems to pass successfully.
Not sure what to copy and paste here but here's the bootstrap.php...
$controller = "students";
$action = "index";
$query = null;
if (isset($_GET['load']))
{
$params = array();
$params = explode("/", $_GET['load']);
$controller = ucwords($params[0]);
if (isset($params[1]) && !empty($params[1]))
{
$action = $params[1];
}
if (isset($params[2]) && !empty($params[2]))
{
$query = $params[2];
}
}
$modelName = $controller;
$controller .= 'Controller';
$load = new $controller($modelName, $action);
if (method_exists($load, $action))
{
$load->{$action}($query);
}
else
{
die('Invalid method. Please check the URL.');
}
Thanks in advance!
Call $this->getRequest()->getParams() from your action controller and check if both parameters are there.
If NO, the problem lies with your routing.
If YES, the problem lies with passing the parameters to your controller method lessonDetails.
Also, lessondetailsAction is missing. (this will be the method called if you visit the url you posted)