i was wondering of how can i show how many items i got in the cart? I did a path in the twig but im not sure how to show it.
this is my controller i have the route and in the twig i call the path with the name (count_panier).
/**
* #Route("/count/{qtt}", name="count_panier")
*/
public function testAction($qtt,Request $req)
{
$qtt = $this->afficherCount($req);
return $this->redirectToRoute('mag',['count'=>$qtt]);
}
//----------------------------------------------
public function afficherCount(Request $req){
$sess = $req->getSession();
$panier = $sess->get('panier',[]);
$qtt = 0;
foreach($panier as $item)
{
$qtt += $item->quantiteCommandee;
}
return $qtt;
}
And this is my twig, this is the part of the top navbar
<div class="menu">
<a class="active" href="{{path('mag')}}">Catalogue</a>
Contact
Crée un compte
Connexion
<a href="panier">Panier
<img width="30" alt="img" src="{{asset('images/cart.png')}}"/></a>
<span id='panierCompteur'>
items</span>
</div>
in your Controller you are passing just one parametere count => '$qtt
So in the Twig file, if you want get it, do this:
{{ count }}
So if you want to get a link that shows how many items you have, do like this:
<span id='panierCompteur'>
{{count}}
items</span>
(you are not usign the $qtt variable so don't pass it)
/**
* #Route("/count", name="count_panier")
*/
public function testAction(Request $req)
{
$qtt = $this->afficherCount($req);
return $this->redirectToRoute('mag',['count'=>$qtt]);
}
//----------------------------------------------
private function afficherCount(Request $req){
$sess = $req->getSession();
$panier = $sess->get('panier',[]);
$qtt = 0;
foreach($panier as $item)
{
$qtt += $item->quantiteCommandee;
}
return $qtt;
}
Of course the first time you render this main page you need to run the function afficherCount() in the index Controller (or whatever is your main controller) and return to the main page the count => '$qtt with all your others arguments.
You are redirecting to another route, so you need to "handle" the redirection if you want to get those parameters:
/**
* #Route("/your-route/{count?}", name="mag", requirements={"count"="\d+"})
*/
public function yourFunction(Request $req, $count)
{
// true if is the first time you render this page or if you don't pass the value
if($count === null){
$count = afficherCount($req);
}
return $this->Render('yourTwigFile.html.twig',['count'=>$count]);
}
{count?} : the ? if for optional parameters so the first time you render this page is not necessary to pass the value in the URL
requirements={"count"="\d+"} : the value can only be an integer
(PS. this function is probably your index)
for more information / examples
Related
what i am trying to do is getting my tvserious and movies from categories class
this is my categories class :
class Category extends Model
{
public function movies()
{
return $this->hasMany(Movie::class);
}
public function tvserious()
{
return $this->hasMany(Tvserious::class);
}
what i tried and it's working
public function CategoryClick($slug){
$media = Category::where('slugid',$slug)->with(['movies' => function($query) {
$query->whereNotNull('title');
},'tvserious' => function($query) {
$query->whereNotNull('title');
}])->inRandomOrder()->paginate(8);
return view('test')->with([
'catclick'=>$media,
'title'=>$slug,
]);
}
the problem with this way is in my blade i have to create a loop for movies and tvserious and the tvserious data will always stay at the end at it will show after the movies loop ends
#foreach($catclick as $media)
#foreach($media->movies as $movie )
{{ $movie->title }}
#endforeach
#foreach($media->tvserious as $tvserious )
{{ $tvserious->title }}
#endforeach
#endforeach
so how can i get both of my movies and serious in my blade mixed together
i don't want all the movies to be at first so where is the problem and how can i fix this ?
this worked pretty well for me ... #first
i made an accessor in my category class
public function getMediaAttribute()
{
return $this->movies->values()->toBase()
->merge($this->tvserious->values())
->sortByDesc(function ($media, $key) {
return $media->updated_at;
});
}
then in my controller
this is my controller function
use Illuminate\Pagination\LengthAwarePaginator as Paginator;
public function CategoryClick($slug){
$all = Category::where('slugid',$slug)->first()->getMediaAttribute(); // calling the accessor
// Then use following code to paginate the results:
$perPage = 10;
$currentPage = app('request')->get('page') ?: 1; // or $request->get('page') if available
$paginator = new Paginator($all, $all->count(), $perPage, $currentPage);
return (dd($paginator));
everything is great now thx for everyone who helped me to solve thix issue :D
Add an accessor to your Category model:
class Category
{
public function getMediaAttribute()
{
return $this->movies->values()->toBase()
->merge($this->tvserious->values())
->sortByDesc(function ($media, $key) {
return $media->updated_at;
});
}
}
Here we used a base collection instead of the Eloquent collection due to merge issues with the Eloquent collection (it does not allow for duplicate keys, thanks #lagbox for pointing it out). After merging both media types together, we also sort the resulting list based on their last update. This means recently touched entries will be listed first.
The newly created list can be accessed with $category->media. Instead of sortByDesc($func) also a simple sortBy('column') or shuffle() (to get a random order) would work.
You can use this code
#php
$moviesCount = $media->movies->count();
$tvseriousCount = $media->tvserious->count();
$maxCount = ($tvseriousCount > $moviesCount) ? $tvseriousCount : $moviesCount;
#endphp
#for ($index = 0; $index < $maxCount; $index++)
#isset($media->movies[$index])
{{ $media->movies[$index]->title }}
#endisset
#isset($media->tvserious[$index])
{{ $media->tvserious[$index]->title }}
#endisset
#endfor
So I have this view that shows a table and two buttons (next/prev). Each button has a query string /?date=next that I capture in my controller using request()->has('date').
<a class="button is-primary is-outlined" href="/?date=prev">Previous</a>
<a class="button is-primary is-outlined" href="/?date=next">Next</a>
The user shall be able to go to next month, and the month after that depending on how many times he clicks on the next/prev button.
Initially, I had two approaches. First, I thought to myself that I can use a $count that increments whenever the user clicks the button in $post->whereMonth('date', $this->count). Second, simply use the Carbon library, $post->date->addMonth().
In both approaches, the date remain the same despite the number of times the next/prev button was clicked.
First approach:
class PostsController extends Controller
{
protected $count;
public function __constructor(){
$this->count = 0;
}
public function show(Hour $post){
if(request()->has('date') == 'next'){
$posts = $post->whereMonth('date', $this->count);
$this->count++;
} else if(request()->has('date') == 'prev'){
$posts = $post->whereMonth('date', $this->count);
$this->count++;
}
return view('user.table', compact('posts'));
}
}
Second approach (favorite):
public function show(Hour $post){
if(request()->has('date') == 'next'){
$posts = $post->date->addMonth();
} else if(request()->has('date') == 'prev'){
$posts = $post->date->subMonth();
}
return view('user.table', compact('posts'));
}
I've seen that Laravel provide the query builder increment, but that only work for columns, and not variables.
Is there a way I can make this work by remembering the previous date as shown in the second approach.
Looks like you just want to display a date. In this case, do this:
public function show(Hour $post)
{
$months = request('months', 0);
if (request('date') === 'next'){
$posts = $post->date->addMonth();
$months++;
} elseif(request('date') === 'prev'){
$posts = $post->date->subMonth();
$months--;
}
return view('user.table', compact('posts', 'months'));
}
And in the view:
<a class="button is-primary is-outlined" href="/?date=next&months={{ $months }}">Previous</a>
<a class="button is-primary is-outlined" href="/?date=next&months={{ $months }}">Next</a>
I have a question. I have a route on my site where I put in session an variable like this:
public function userCaptcha(){
$_SESSION['isFacebookRegistration'] = 0;
}
Now I have another route witch render a view :
public function index(){
$this->session = $_SESSION;
return $this->render('template/index.twig');
}
In the index template I do :
{{ dump(session.isFacebookRegistration) }}
{% set session = session|merge({'isFacebookRegistration' : 3}) %}
I access the first route : userCaptcha() one time but the route index() 2 times, normally I need to see the first time 0 and the second 3. But I see only the 0 for 2 times. Can you help me please? The idea is to show for first time 0 for the rest 3. Thx in advance
You cannot set a PHP var on Twig side. Every time your view is reloaded, changes you made to your variable will be lost. You can try something like this:
public function userCaptcha(){
$_SESSION['isFacebookRegistration'] = 0;
}
public function index(){
if (isset($_SESSION['flag'])) {
$_SESSION['isFacebookRegistration'] = 3;
}
$_SESSION['flag'] = true;
$this->session = $_SESSION;
return $this->render('template/index.twig');
}
This way, executing index() for first time won't change isFacebookRegistration value, but will set a flag. Next time, the conditial will be true an isFacebookRegistration will change.
I'm trying to achieve the following scenario:
1. user display the page addBook.php
2. user starts filling the form
3. but when he wants to select the book Author from the Author combo box, the Author is not yet created in the database so the user clicks a link to add a new Author
5. user is redirected to addAuthor.php
6. the user fill the form and when he submits it, he goes back to addBook.php with all the previous data already present and the new Author selected.
The things is: I have scenarios where there is more than one level of recursion. (Example: Add Book => Add Author => Add Country)
How can I do that?
At step #3, the link submit the form so that I can save it in session.
To handle recursion, I can use a Stack and push the current from on the Stack each time I click a link. And pop the last form of the Stack when the user completes the action correctly or click a cancel button.
My problem is:
How can I handle the back button of the browser?
If instead of clicking the "cancel" button, the user click on the back button, how could I kown that I need to pop the last element?
Do you known some common pattern to achieve that?
You must use javascript on the client and hook into the window unload event, serialize the form and send the answer to the server, which saves it in the session.
$(window).unload(function() {
$.ajax({
url : 'autosave.php',
data : $('#my_form').serialize()
});
});
on server
// autosave.php
$_SESSION['autosave_data'] = $_POST['autosave_data'];
// addbook.php
if (isset($_SESSION['autosave_data'])) {
// populate the fields
}
This is the solution I developed to answer my problem.
As the problem was not a client side problem but truly a server side one. Following the php classes I used in my project:
First the main class of the stack functionality. The inclusion need to be done before the session_start as the object will be stored in the session
class Stack {
private $stack;
private $currentPosition;
private $comeFromCancelledAction = false;
public function __construct() {
$this->clear();
}
/* ----------------------------------------------------- */
/* PUBLICS METHODS */
/* ----------------------------------------------------- */
/**
* Clear the stack history
*/
public function clear() {
$this->stack = array();
$this->currentPosition = -1;
}
/**
* get the current position of the stack
*/
public function getCurrentPosition() {
return $this->currentPosition;
}
/**
* Add a new element on the stack
* Increment the current position
*
* #param $url the url to add on the stack
* #param $data optionnal, the data that could be stored with this $url
*/
public function add($url, &$data = array()) {
if (count($this->stack) != $this->currentPosition) {
// the currentPosition is not the top of the stack
// need to slice the array to discard dirty urls
$this->stack = array_slice($this->stack, 0, $this->currentPosition+1);
}
$this->currentPosition++;
$this->stack[] = array('url' => $url, 'data' => $data, 'previousData' => null, 'linked_data' => null);
}
/**
* Add the stack position parameter in the URL and do a redirect
* Exit the current script.
*/
public function redirect() {
header('location:'.$this->addStackParam($this->getUrl($this->currentPosition)), 301);
exit;
}
/**
* get the URL of a given position
* return null if the position is not valid
*/
public function getUrl($position) {
if (isset($this->stack[$position])) {
return $this->stack[$position]['url'];
} else {
return null;
}
}
/**
* get the Data of a given position
* return a reference of the data
*/
public function &getData($position) {
if (isset($this->stack[$position])) {
return $this->stack[$position]['data'];
} else {
return null;
}
}
/**
* Update the context of the current position
*/
public function storeCurrentData(&$data) {
$this->stack[$this->currentPosition]['data'] = $data;
}
/**
* store some data that need to be fixed in sub flow
* (for example the id of the parent object)
*/
public function storeLinkedData($data) {
$this->stack[$this->currentPosition]['linked_data'] = $data;
}
/**
* Update the context of the current position
*/
public function storePreviousData(&$data) {
$this->stack[$this->currentPosition]['previousData'] = $data;
}
/**
* Compute all linked data for every positions before the current one and return an array
* containing all keys / values
* Should be called in sub flow to fixed some data.
*
* Example: if you have tree pages: dad.php, mum.php and child.php
* when creating a "child" object from a "dad", the dad_id should be fixed
* but when creating a "child" object from a "mum", the mum_id should be fixed and a combo for choosing a dad should be displayed
*/
public function getLinkedData() {
$totalLinkedData = array();
for($i = 0; $i < $this->currentPosition; $i++) {
$linkedData = $this->stack[$i]['linked_data'];
if ($linkedData != null && count($linkedData) > 0) {
foreach($linkedData as $key => $value) {
$totalLinkedData[$key] = $value;
}
}
}
return $totalLinkedData;
}
/**
* Main method of the Stack class.
* Should be called on each page before any output as this method should do redirects.
*
* #param $handler StackHandler object that will be called at each step of the stack process
* Let the caller to be notified when something appens.
* #return the data
*/
public function initialise(StackHandler $handler) {
if (!isset($_GET['stack']) || !ctype_digit($_GET['stack'])) {
// no stack info, acces the page directly
$this->clear();
$this->add($this->getCurrentUrl()); //add the ?stack=<position number>
$this->storeLinkedData($handler->getLinkedData());
$this->redirect(); //do a redirect to the same page
} else {
// $_GET['stack'] is set and is a number
$position = $_GET['stack'];
if ($this->currentPosition == $position) {
// ok the user stay on the same page
// or just comme from the redirection
if (!empty($_POST['action'])) {
// user submit a form and need to do an action
if ($_POST['action'] == 'cancel') {
$currentData = array_pop($this->stack);
$this->currentPosition--;
$handler->onCancel($currentData);
// redirect to the next page with ?stack=<current position + 1>
$this->redirect();
} else {
// store the action for future use
$this->stack[$this->currentPosition]['action'] = $_POST['action'];
$currentData = $this->getData($this->currentPosition);
list($currentData, $nextUrl) = $handler->onAction($currentData, $_POST['action']);
// store current form for future use
$this->storeCurrentData($currentData);
// add the new page on the stack
$this->add($nextUrl);
// redirect to the next page with ?stack=<current position + 1>
$this->redirect();
}
} else if (isset($this->stack[$this->currentPosition]['action'])) {
// no action, and an action exists for this position
$currentData = $this->getData($this->currentPosition);
$action = $this->stack[$this->currentPosition]['action'];
if ($this->comeFromCancelledAction) {
//we return from a cancelled action
$currentData = $handler->onReturningFromCancelledAction($action, $currentData);
$this->comeFromCancelledAction = false;
} else {
$previousData = $this->getPreviousData();
if ($previousData != null) {
//we return from a sucessful action
$currentData = $handler->onReturningFromSuccesAction($action, $currentData, $previousData);
$this->resetPreviousData();
}
}
$this->storeCurrentData( $currentData );
}
$currentData = $this->getData($this->currentPosition);
if ($currentData == null) {
$currentData = $handler->getInitialData();
$this->storeCurrentData( $currentData );
}
return $currentData;
} else if ($this->getUrl($position) == $this->getCurrentUrl()) {
// seems that the user pressed the back or next button of the browser
// set the current position
$this->currentPosition = $position;
return $this->getData($position);
} else {
// the position does not exist or the url is incorrect
// redirect to the last known position
$this->redirect();
}
}
}
/**
* call this method after completing an action and need to redirect to the previous page.
* If you need to give some data to the previous action, use $dataForPreviousAction
*/
public function finishAction($dataForPreviousAction = null) {
$pop = array_pop($this->stack);
$this->currentPosition--;
$this->storePreviousData($dataForPreviousAction);
$this->redirect();
}
/* ----------------------------------------------------- */
/* PRIVATE METHODS */
/* ----------------------------------------------------- */
/**
* get the previous data for the current position
* used when a sub flow finish an action to give some data to the parent flow
*/
private function &getPreviousData() {
if (isset($this->stack[$this->currentPosition])) {
return $this->stack[$this->currentPosition]['previousData'];
} else {
return null;
}
}
/**
* get the current url without the stack parameter
*
* Attention: this method calls "basename" on PHP_SELF do strip the folder structure
* and assume that every pages are in the same directory.
*
* The "stack" parameter is removed from the query string
*
* Example: for the page "http://myserver.com/path/to/a.php?id=1&stack=2"
* PHP_SELF will be: /path/to/a.php
* QUERY_STRING wille be: id=1&stack=2
* This method will return: "a.php?id=1"
*/
private function getCurrentUrl() {
$basename = basename($_SERVER['PHP_SELF']);
if ($_SERVER['QUERY_STRING'] != '') {
return $basename.$this->removeQueryStringKey('?'.$_SERVER['QUERY_STRING'], 'stack');
} else {
return $basename;
}
}
/**
* add the "stack" parameter in an url
*/
private function addStackParam($url) {
return $url . (strpos($url, '?') === false ? '?' : '&') . 'stack=' . $this->currentPosition;
}
/**
* Usefull private method to remove a key=value from a query string.
*/
private function removeQueryStringKey($url, $key) {
$url = preg_replace('/(?:&|(\?))'.$key.'=[^&]*(?(1)&|)?/i', "$1", $url);
return $url != '?' ? $url : '';
}
/**
* reset the previous data so that the data are not used twice
*/
private function resetPreviousData() {
$this->stack[$this->currentPosition]['previousData'] = null;
}
}
Then define the abstract StackHandler class
abstract class StackHandler {
/**
* return the initial data to store for this current page
*/
public function &getInitialData() {
return null;
}
/**
* return an array containing the key/values that need to be fixed in sub flows
*/
public function getLinkedData() {
return null;
}
/**
* user ask to go to a sub page
*/
public function onAction(&$currentData, $action) {
$currentData = $_POST;
$nextUrl = $_POST['action'];
return array($currentData, $nextUrl);
}
public function onCancel(&$currentData) {
}
public function onReturningFromCancelledAction($action, &$currentData) {
}
public function onReturningFromSuccesAction($action, &$currentData, $previousData) {
}
}
Then add the following lines at the top of your pages. Adapt the handler it to fit your needs.
// be sure that a stack object exist in the session
if (!isset($_SESSION['stack'])) {
$_SESSION['stack'] = new Stack();
}
$myDad = $_SESSION['stack']->initialise(new DadStackHandler());
class DadStackHandler extends StackHandler {
/**
* return the initial data to store for this current page
*/
public function &getInitialData() {
if(! empty($_GET['id_dad']) && ctype_digit($_GET['id_dad'])){
// update
$myDad = new Dad($_GET['id_dad']);
} else {
// creation
$myDad = new Dad();
}
return $myDad;
}
/**
* return an array containing the key/values that need to be fixed in sub flows
*/
public function getLinkedData() {
$linkedData = array();
if (! empty($_GET['id_dad']) && ctype_digit($_GET['id_dad'])) {
$linkedData['id_dad'] = $_GET['id_dad'];
}
return $linkedData;
}
/**
* user ask to go to a sub page
*/
public function onAction(&$myDad, $action) {
//in order not to loose user inputs, save them in the current data
$myDad->name = $_POST['name'];
$nextUrl = null;
// find the next url based on the action name
if ($action == 'child') {
$nextUrl = 'child.php';
}
return array($myDad, $nextUrl);
}
public function onCancel(&$myDad) {
// probably nothing to do, leave the current data untouched
// or update current data
return $myDad;
}
public function onReturningFromCancelledAction($action, &$myDad) {
// probably nothing to do, leave the current data untouched
// called when returning from child.php
return $myDad;
}
public function onReturningFromSuccesAction($action, &$myDad, $newId) {
// update the id of the foreign field if needed
// or update the current data
// not a good example as in real life child should be a list and not a foreign key
// $myDad->childId = $newId;
$myDad->numberOfChildren++;
return $myDad;
}
}
...
if (user submit form and all input are correct) {
if ($myDad->save()) {
// the user finish an action, so we should redirect him to the previous one
if ($_SESSION['stack']->getCurrentPosition() > 0) {
$_SESSION['stack']->finishAction($myDad->idDad);
} else {
// default redirect, redirect to the same page in view more or redirect to a list page
}
}
}
I hope this could help others.
I have been reading a lot about how and why to use an MVC approach in an application. I have seen and understand examples of a Model, I have seen and understand examples of the View.... but I am STILL kind of fuzzy on the controller. I would really love to see a thorough enough example of a controller(s). (in PHP if possible, but any language will help)
Thank you.
PS: It would also be great if I could see an example of an index.php page, which decides which controller to use and how.
EDIT: I know what the job of the controller is, I just don't really understand how to accomplish this in OOP.
Request example
Put something like this in your index.php:
<?php
// Holds data like $baseUrl etc.
include 'config.php';
$requestUrl = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$requestString = substr($requestUrl, strlen($baseUrl));
$urlParams = explode('/', $requestString);
// TODO: Consider security (see comments)
$controllerName = ucfirst(array_shift($urlParams)).'Controller';
$actionName = strtolower(array_shift($urlParams)).'Action';
// Here you should probably gather the rest as params
// Call the action
$controller = new $controllerName;
$controller->$actionName();
Really basic, but you get the idea... (I also didn't take care of loading the controller class, but I guess that can be done either via autoloading or you know how to do it.)
Simple controller example (controllers/login.php):
<?php
class LoginController
{
function loginAction()
{
$username = $this->request->get('username');
$password = $this->request->get('password');
$this->loadModel('users');
if ($this->users->validate($username, $password))
{
$userData = $this->users->fetch($username);
AuthStorage::save($username, $userData);
$this->redirect('secret_area');
}
else
{
$this->view->message = 'Invalid login';
$this->view->render('error');
}
}
function logoutAction()
{
if (AuthStorage::logged())
{
AuthStorage::remove();
$this->redirect('index');
}
else
{
$this->view->message = 'You are not logged in.';
$this->view->render('error');
}
}
}
As you see, the controller takes care of the "flow" of the application - the so-called application logic. It does not take care about data storage and presentation. It rather gathers all the necessary data (depending on the current request) and assigns it to the view...
Note that this would not work with any framework I know, but I'm sure you know what the functions are supposed to do.
Imagine three screens in a UI, a screen where a user enters some search criteria, a screen where a list of summaries of matching records is displayed and a screen where, once a record is selected it is displayed for editing. There will be some logic relating to the initial search on the lines of
if search criteria are matched by no records
redisplay criteria screen, with message saying "none found"
else if search criteria are matched by exactly one record
display edit screen with chosen record
else (we have lots of records)
display list screen with matching records
Where should that logic go? Not in the view or model surely? Hence this is the job of the controller. The controller would also be responsible for taking the criteria and invoking the Model method for the search.
<?php
class App {
protected static $router;
public static function getRouter() {
return self::$router;
}
public static function run($uri) {
self::$router = new Router($uri);
//get controller class
$controller_class = ucfirst(self::$router->getController()) . 'Controller';
//get method
$controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction());
if(method_exists($controller_class, $controller_method)){
$controller_obj = new $controller_class();
$view_path = $controller_obj->$controller_method();
$view_obj = new View($controller_obj->getData(), $view_path);
$content = $view_obj->render();
}else{
throw new Exception("Called method does not exists!");
}
//layout
$route_path = self::getRouter()->getRoute();
$layout = ROOT . '/views/layout/' . $route_path . '.phtml';
$layout_view_obj = new View(compact('content'), $layout);
echo $layout_view_obj->render();
}
public static function redirect($uri){
print("<script>window.location.href='{$uri}'</script>");
exit();
}
}
<?php
class Router {
protected $uri;
protected $controller;
protected $action;
protected $params;
protected $route;
protected $method_prefix;
/**
*
* #return mixed
*/
function getUri() {
return $this->uri;
}
/**
*
* #return mixed
*/
function getController() {
return $this->controller;
}
/**
*
* #return mixed
*/
function getAction() {
return $this->action;
}
/**
*
* #return mixed
*/
function getParams() {
return $this->params;
}
function getRoute() {
return $this->route;
}
function getMethodPrefix() {
return $this->method_prefix;
}
public function __construct($uri) {
$this->uri = urldecode(trim($uri, "/"));
//defaults
$routes = Config::get("routes");
$this->route = Config::get("default_route");
$this->controller = Config::get("default_controller");
$this->action = Config::get("default_action");
$this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : '';
//get uri params
$uri_parts = explode("?", $this->uri);
$path = $uri_parts[0];
$path_parts = explode("/", $path);
if(count($path_parts)){
//get route
if(in_array(strtolower(current($path_parts)), array_keys($routes))){
$this->route = strtolower(current($path_parts));
$this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : '';
array_shift($path_parts);
}
//get controller
if(current($path_parts)){
$this->controller = strtolower(current($path_parts));
array_shift($path_parts);
}
//get action
if(current($path_parts)){
$this->action = strtolower(current($path_parts));
array_shift($path_parts);
}
//reset is for parameters
//$this->params = $path_parts;
//processing params from url to array
$aParams = array();
if(current($path_parts)){
for($i=0; $i<count($path_parts); $i++){
$aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null;
$i++;
}
}
$this->params = (object)$aParams;
}
}
}
Create folder structure
Setup .htaccess & virtual hosts
Create config class to build config array
Controller
Create router class with protected non static, with getters
Create init.php with config include & autoload and include paths (lib, controlelrs,models)
Create config file with routes, default values (route, controllers, action)
Set values in router - defaults
Set uri paths, explode the uri and set route, controller, action, params ,process params.
Create app class to run the application by passing uri - (protected router obj, run func)
Create controller parent class to inherit all other controllers (protected data, model, params - non static)
set data, params in constructor.
Create controller and extend with above parent class and add default method.
Call the controller class and method in run function. method has to be with prefix.
Call the method if exisist
Views
Create a parent view class to generate views. (data, path) with default path, set controller, , render funcs to
return the full tempalte path (non static)
Create render function with ob_start(), ob_get_clean to return and send the content to browser.
Change app class to parse the data to view class. if path is returned, pass to view class too.
Layouts..layout is depend on router. re parse the layout html to view and render
Please check this:
<?php
global $conn;
require_once("../config/database.php");
require_once("../config/model.php");
$conn= new Db;
$event = isset($_GET['event']) ? $_GET['event'] : '';
if ($event == 'save') {
if($conn->insert("employee", $_POST)){
$data = array(
'success' => true,
'message' => 'Saving Successful!',
);
}
echo json_encode($data);
}
if ($event == 'update') {
if($conn->update("employee", $_POST, "id=" . $_POST['id'])){
$data = array(
'success' => true,
'message' => 'Update Successful!',
);
}
echo json_encode($data);
}
if ($event == 'delete') {
if($conn->delete("employee", "id=" . $_POST['id'])){
$data = array(
'success' => true,
'message' => 'Delete Successful!',
);
}
echo json_encode($data);
}
if ($event == 'edit') {
$data = $conn->get("select * from employee where id={$_POST['id']};")[0];
echo json_encode($data);
}
?>