CodeIgniter controller doesn't recognize function - model-view-controller

This is something strange.
The controller function called product just doesn't work, but any other name works. See the following code:
namespace App\Controllers;
class Shop extends BaseController {
public function index() {
return view('shop');
}
public function asdf(){
return view('product');
}
public function product(){
return view('product');
}
}
Calling the function asdf (or whatever name it is), works. But I get a 404 if I call the /shop/product.
How to explain (and hopefully solve) it?

Related

Setting getKeyRouteName dependant on route (web or api)

Tried looking for the answer to this everywhere but having no luck so far...
Basically I want my web route to use a slug for its URL, but I want to use ID for the API route. So...
http://myurl.com/chapter/my-chapter-slug
and
http://myurl.com/api/chapter/1234
Have tried various combinations of things in the getRouteKeyName method (if(Request::route()->named('myapiroute'), if(Request::isJson() etc...) but I think these might be being checked against the page it's running on, rather than the route I'm trying to generate?
I'm thinking maybe I need to extend the base model to have a separate one to use with my API maybe?
So I'd have...
class Chapter extends Model
{
public function getRouteKeyName()
{
return 'slug';
}
....
}
and then...
class ApiChapter extends Chapter
{
public function getRouteKeyName()
{
return 'id';
}
....
}
But not sure how I'd structure this in the most "Laravel" way? Or is there a better/tidier solution?
define your route for example like
Route::get('chapters/{chapter}','ChapterController#show'); // find by slug
Route::get('api/chapters/{chapter}','ApiChapterController#show'); // find by id
for web controller
class ChapterController extends Controller
{
public function show(Request $request,$slug)
{
$instance = Model::whereSlug($slug)->first();
}
}
for api
class ApiChapterController extends Controller
{
public function show(Request $request,$id)
{
$instance = Model::find($id);
}
}
You can define 2 different routes for that but unfortunatelly you will not be able to use model binding and you will have to look for the model like:
public function show(Request $request,$slug) {
$instance = Model::whereSlug($slug)->first();
}
as shown below: https://stackoverflow.com/a/48115385/6525417

Pass variable from one controller to another laravel 5.4

I am trying to pass the request variable from a form request to another controller (the second controller is going to have a lot of code in it so I want to use it to keep the main controller clean), but when I try and pass the variable over, nothing happens, the variable data isn't sent over.
Here is my current code:
class mainController extends Controller{
public function store(Request $request)
{
//validation
$otherClass = (new secondController)->createDBEntry($request);
}
}
class secondController extends Controller{
public function createDBEntry($request)
{
return $request;
}
}
However, nothing is passed from the $request into the secondController. If I echo something in the secondController it works no problem, so I know it's being called, but the data isn't being sent over. What am I missing here? Keep in mind I am fairly new to laravel and I am using 5.4.
Your code works just fine. You are just expecting a behavior that is never going to happen though because:
new secondController instantiates secondController
createDBEntry($request) calls the method createDBEntry passed
with $request
The returned value is stored in the variable $otherClass
And that's it! nothing more is (and will be) happening. If you want to see the value of $otherClass (and see your code working) you have to return it:
class mainController extends Controller
{
public function store(Request $request)
{
$otherClass = new secondController
$otherClass->createDBEntry($request);
return $otherClass;
}
}
class secondController extends Controller
{
public function createDBEntry($arg)
{
return $arg;
}
}

How to call BaseController public function from child classes in Laravel (4)?

I have a CustomController. For not to repeat myself, I defined getVars function in BaseController. I want to call getVars function from some functions in CustomController.
However, Laravel returns 404 error without any exception. What is wrong?
class BaseController extends Controller {
public function getVars($var1, $var2, $var3=Null, $var4=Null) {
return [];
}
}
class CustomController extends BaseController {
public function doBla1($var1, $var2) {
$vars = $this->getVars();
}
public function doBla2() {
$vars = $this->getVars();
}
public function doBla3() {
$vars = $this->getVars();
}
}
Sorry :( I found the reason of error. The names of doBla1 and getVars functions are same. This results in a 404 error. Sorry :(
$this is useful when you have method/function defined in same controller.
For functions inside parent controller you can use
Parent::getVars($var1, $var2)

CodeIgniter - Replace redunant JSON conversion

I recently started using Codeigniter after having a structural problem in one of my Ajax-heavy applications. (You can read up on it if you want in my previous question)
I have a fairly short question. Currently I am making a lot of Ajax requests to different controllers. I open the controllers like this:
public function __construct()
{
parent::__construct();
$this->output->set_content_type('application/json');
}
And at the end of every function I do the following:
$this->returnValue['result'] = "ReturnedInfo";
$this->returnValue = json_encode($this->returnValue);
$this->output->set_output($this->returnValue);
The code is pretty clear in itself, but I don't want to keep repeating myself. The codeigniter manual says to do the following:
$this->output
->set_content_type('application/json')
->set_output(json_encode(array('foo' => 'bar')));
But I would still be repeating myself. Also, I don't want to add a function to every controller that does this, even if it does decrease redundancy.
Since all of my controllers return JSON, is there a way to set this globally in a config file maybe, or in any other way?
TL;DR I have this same piece of code in every controller/function. Since the output type is always the same, just not the result, is there a way to automate this process across every controller/function?
Create an Ajax_Controller that extends MY_Controller that extends CI_Controller.
The Ajax Controller will then inherit from both Controllers.
class Ajax_Controller extends MY_Controller
{
public function __construct()
{
parent::__construct();
if(!$this->input->is_ajax_request()) return show_error('Invalid Request');
}
public function jsonOutput($json)
{
//some data checking here....
return $this->output
->set_content_type('application/json')
->set_header("HTTP/1.1 200 OK")
->set_output($json);
}
}
-
class User extends Ajax_Controller
{
public function __construct()
{
parent::__construct();
}
public function userMethod()
{
$json = json_encode(array(
'' => ''
));
$this->jsonOutput($json);
}
}
Extend your controllers from your own base class rather than CI_Controller and put your repeatedly-used function(s) and constructor code in there. Something like:
class BaseController extends CI_Controller {
protected function index() {
$this->returnValue['result'] = "ReturnedInfo";
$this->returnValue = json_encode($this->returnValue);
$this->output->set_output($this->returnValue);
}
}
class Specific extends BaseController {
public function index() {
//do controller-specific stuff
parent::index();
}
}
I abstract this further if I have groups of controllers with shared code; for example, if I had a bunch of controllers that require the user to be logged-in I create AuthenticatedController, which extends BaseController and add session checks etc.

Code Igniter controller - can't use uri->segment with function index()?

I'm working with code igniter and for some reason, the url http://mysite.com/account/100 gives me a 404 error but http://mysite.com/account actualy works. Here's what my controller account.php looks like.
class account extends Controller {
function account()
{
parent::Controller();
}
function index()
{
echo 'hello';
echo $this->uri->segment(2);
}
}
Any idea what's wrong?
I just tested a simple account class like you have and it is trying to call 100 as a method of account, instead your URL after index.php should be account/index/100 and it works fine.
This can be solved using routing for example.
$route['account/(:num)'] = "accounts/index/$1";
is what you are looking for. You can look over the URI Routing user guide
for more info.
CodeIgniter requires that your controller name be capitalized, and the filename lowercase so try changing your controller to.
class Account extends Controller { }
and your filename account.php
Add this route and you are good
$route['account/(:any)'] = "account/index/$1";
This is not working because when you request http://example.com/account, it looks index() method.
But when you request http://example.com/account/100, is looking for 100() method. Which is not present.
You may tweak the code like this.
class account extends Controller {
public function account()
{
parent::Controller();
}
public function index()
{
echo 'hello';
}
public function id(){
echo $this->uri->segment(2);
}
public function alternative($id){
echo $id;
}
}
you'll call url like this: http://example.com/account/id/100
or you can do like this
http://example.com/account/alternative/100

Resources