REST_Controller.php is not working in codeigniter - codeigniter

I am going to use REST_Controller.php to make rest api's. (using codeigniter v3 on ubnatu 15)
from link https://github.com/chriskacerguis/codeigniter-restserver
on calling
localhost/rest_api_ci/api/example/user/1
Showing me error
Fatal error: Class 'REST_Controller' not found in /var/www/html/rest_api_ci/application/controllers/api/Example.php on line 21
A look of Example.php file
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
// This can be removed if you use __autoload() in config.php OR use Modular Extensions
/** #noinspection PhpIncludeInspection */
require(APPPATH.'libraries/REST_Controller.php');
/**
* This is an example of a few basic user interaction methods you could use
* all done with a hardcoded array
*
* #package CodeIgniter
* #subpackage Rest Server
* #category Controller
* #author Phil Sturgeon, Chris Kacerguis
* #license MIT
* #link https://github.com/chriskacerguis/codeigniter-restserver
*/
class Example extends REST_Controller {
function __construct()
{

change your url from
localhost/rest_api_ci/api/example/user/1
to
http://localhost/rest_api_ci/index.php/api/Example/users

Removing Unnecessary Namespaces in REST_Server.php and Format.php helped me.

After
require(APPPATH.'libraries/REST_Controller.php');
you need to add the namespace:
// use namespace
use Restserver\Libraries\REST_Controller;
... I ran into this issue few minutes ago and it worked with me

I think its the path issue, same answer is given here Hope it will help you or someone else.
Thanks

Related

Is the includeFile() Method necessary?

I'm just curious that why don`t official team use include $file; directly in ClassLoader.php ?
Thanks in advance!
The code docs are pretty clear about that:
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}
It isolates the loading code so it can't access $this or $self.

CodeIgniter : accessing views from sub folders

I am trying to learn codeigniter in these days and I am struggling understanding the structure of views, controllers and models according to routes in order to maintain security.
So, how should we structure our views, controllers and models for admin backend and user backend, i mean folders, sub-folders and routing?
first I wanna mention how i am putting my files in order :
My route :
$route['default_controller'] = 'site/home';
$route['home'] = 'site/home';
so here a default controller is Site.php :
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Site extends CI_Controller {
/**
* Index Page for this controller.
*
* Maps to the following URL
* http://example.com/index.php/welcome
* - or -
* http://example.com/index.php/welcome/index
* - or -
* Since this controller is set as the default controller in
* config/routes.php, it's displayed at http://example.com/
*
* So any other public methods not prefixed with an underscore will
* map to /index.php/welcome/<method_name>
* #see https://codeigniter.com/user_guide/general/urls.html
*/
public function index()
{
$data['body']='site/home';
$this->load->view('includes/template',$data);
}
public function home(){
$data['body']='site/home';
$this->load->view('includes/template',$data);
}
public function AnotherMethod(){
$data['body']='site/AnotherPage';
$this->load->view('includes/template',$data);
}
And my view template is (views/includes/template.php) :
<?php
//load head
$this->load->view('includes/header');
//load body
$this->load->view($body);
//load footer
$this->load->view('includes/footer');
?>
So If i am putting things like this, I am having problem to accessing views from sub folders. As an example,
directory : views/site/userbackend/index.php
or views/site/adminbackend/index.php
And there are also controllers and models in sub folders according to the admin backend and user backend.
How i am going to access them?
I am here just trying to show what kind of problems i am having..
So now all the answers of the questions can be solved if you just direct me to the scenario how experts do and structure there components and what is the best practices.
I know i have made this question complex with many things at a time, i am sorry for that, if you want me to be clear more on one subject just tell me, i will update my question.
Need a helping hand here.
Thanks in Advance !
All views are available to all controllers, if:
View file exists
You specify the correct path to it
For views/site/userbackend/index.php should be $data['body'] = 'site/userbackend/index';
If my simple projects I have this structure:
controllers
backend
Admin.php
Admin_users.php
...
Main.php
News.php
...
views
backend
main
header.php
footer.php
users
view_list.php
view_form.php
frontend
main
header.php
footer.php
sidebar.php
news
view_list.php
view_item.php
mainpage.php
...
In view_list.php:
$this->load->view('frontend/main/header');
<news list>
$this->load->view('frontend/main/footer');
And I practice HMVC.
I had a similar issue and got it working for views in subfolders by adding .php to the view path, just like this:
$this->load->view('includes/template.php',$data);

Subclassing Migrator not working for namespaced migration

I have some namespaced migrations, and I can't get past the Class Not Found errors due to namespacing. In an earlier question, Antonio Carlos Ribeiro stated:
Laravel migrator doesn't play nice with namespaced migrations. Your best bet in this case is to subclass and substitute the Migrator class, like Christopher Pitt explains in his blog post: https://medium.com/laravel-4/6e75f99cdb0.
I have tried doing so (followed by composer dump-autoload, of course), but am continuing to receive Class Not Found errors. I've got the project files set up as
inetpub
|--appTruancy
|--database
|--2015_04_24_153942_truancy_create_districts.php
|--MigrationsServiceProvider.php
|--Migrator.php
The migration file itself is as follows:
<?php
namespace Truancy;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class TruancyCreateDistricts extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('districts', function($table) {
$table->string('id')->unique()->primary()->nullable(false);
$table->string('district');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('districts');
}
}
Migrator.php is as follows:
namespace Truancy;
use Illuminate\Database\Migrations\Migrator as Base;
class Migrator extends Base{
/**
* Resolve a migration instance from a file.
*
* #param string $file
* #return object
*/
public function resolve($file)
{
$file = implode("_", array_slice(explode("_", $file), 4));
$class = "Truancy\\" . studly_case($file);
return new $class;
}
}
MigrationServiceProvider.php is as follows:
<?php
namespace Truancy;
use Illuminate\Support\ServiceProvider;
class TruancyServiceProvider extends ServiceProvider{
public function register()
{
$this->app->bindShared(
"migrator",
function () {
return new Migrator(
$this->app->make("migration.repository"),
$this->app->make("db"),
$this->app->make("files")
);
}
);
}
}
The lines generated in autoload_classmap.php are as expected:
'Truancy\\Migrator' => $baseDir . '/appTruancy/database/migrations/Migrator.php',
'Truancy\\TruancyCreateDistricts' => $baseDir . '/appTruancy/database/migrations/2015_04_24_153942_truancy_create_districts.php',
'Truancy\\TruancyServiceProvider' => $baseDir . '/appTruancy/database/migrations/MigrationsServiceProvider.php'
I'm calling php artisan migrate --path="appTruancy/database/migrations" and I receive the error:
PHP Fatal error: Class 'TruancyCreateDistricts' not found in
C:\inetpub\laravel\vendor\laravel\framework\src\Illuminate\Database
\Migrations\Migrator.php on line 297
I know I must be doing something dumb (my instinct is $class = "Truancy\\" . studly_case($file); in Migrator.php is wrong), but I can't unscrew this lightbulb. The migrate command is obviously successfully finding my migrations file, and the correct classname is in the classmap, so it has to be somewhere in the process of resolving the classname itself from the file, which the subclass and substitution is supposed to address. Any suggestions as to where I've gone wrong?
Ok, I've gotten this working. It turns out that the Medium.com article assumes you'd just know where to put the files he talks about, which I didn't. I've made several changes, and now everything is working correctly:
I created a new appTruancy\providers subfolder, and add it to composer.json
I moved both Migrator.php and MigrationServiceProvider.php into the new folder
I changed the namespace in both of those files to Truancy\Providers to match the directory structure
I added 'Truancy\Providers\MigrationsServiceProvider' to the providers array in appTruancy\config\app.php
I added a \ in front of Schema in the migration file to reference the base namespace.
I ran dump-autoload to update the classmap
This is one of those cases where I'm not 100% certain that all of the changes were required, but the layout does make sense so I'm happy with it. So, in a nutshell, if you're trying to namespace your migrations, you need to subclass the Migrator class as described in the Medium.com article listed above, but you then need to register the service provider in config\app, making sure the class names in both files are consistent.

Zend Framework Session Management. Zend_Session_Namespace not found

I am referring to this documentation on how to use sessions with Zend Framework:
http://framework.zend.com/manual/1.12/en/learning.multiuser.sessions.html
I have started with a skeletal application at this point the only thing I have modified is the controller. I am posting the code for Application module controller:
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* #link http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
* #copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* #license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
public function indexAction()
{
$mysession = new Zend_Session_Namespace('mysession');
if (!isset($mysession->counter)) {
$mysession->counter = 1000;
} else {
$mysession->counter++;
}
if ($mysession->counter > 1999) {
unset($mysession->counter);
}
return new ViewModel();
}
}
The first thing I see when I go to the route is:
Fatal error: Class 'Application\Controller\Zend_Session_Namespace' not found in C:\Program Files (x86)\Zend\Apache2\htdocs\zf2-sessioncounter\module\Application\src\Application\Controller\IndexController.php on line 19
So I am thinking this has to do with a use Zend_Session_Namespace at this point or perhaps it is because my application is not set up for Zend_Application? Would this be a correct place to put the session php?
Zend_Session_Namespace is actually a component of ZF1 - which shouldn't be used in ZF2 application because of many reasons (NOT using proper namespace mechanism being the most important).
Try Zend\Session\Container instead:
use Zend\Session\Container;
// ...
$mysession = new Container('mysession');

Codeigniter Call Controller From Controller

After the last two comments, I'll dump out my real code and maybe it will help out:
Here is the landing Controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Businessbuilder extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
$RTR = $GLOBALS["RTR"];
// import the necessary libraries
$this->load->model("site_pages");
$RTR = $GLOBALS["RTR"];
// get the current site
$site = current_site();
// get the requesting url
$class = $RTR->uri->rsegments[1];
$function = $RTR->uri->rsegments[2];
// get the current function and class
$current_method = explode("::", __METHOD__);
// get the real class name that is going to be called
$site_page = $this->site_pages->get(array("display_name"=>$class, "id"=>$site->id));
$site_page = $site_page->result();
if(count($site_page) == 1)
{
$site_page = $site_page[0];
// set the class name to be called
$class = $site_page->class_name;
}
// only execute if the requested url is not the current url
if(!(strtolower($class) == strtolower($current_method[0]) && strtolower($function) == strtolower($current_method[1])))
{
if(!file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$class.EXT))
{
show_404($RTR->fetch_directory().$class);
exit;
}
// include the required file. I use require once incase it is a file that I've already included
require_once(APPPATH.'controllers/'.$RTR->fetch_directory().$class.EXT);
// create an instance of the class
$CI = new $class();
if(method_exists($CI, $function))
// call the method
call_user_func_array(array(&$CI, $function), array_slice($RTR->uri->rsegments, 2));
else
{
show_404($RTR->fetch_directory().$class);
exit;
}
}
}
}
here is an example of a dynamic controller that will be called:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Public_homepage extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
echo "<br /><br /><br />";
$this->load->model("sites");
$style = $this->sites->get(array("id"=>1)); // fail here, sites not defined
//print_r($style);
exit;
$view_params = array();
$view_params["site_id"] = $this->site_id;
$this->load->view('public_homepage', $view_params);
}
}
Here is my model that I am using:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Sites extends CI_Model
{
function __construct()
{
parent::__construct();
}
function get($search = array())
{
return $this->db->query("SELECT * FROM sites"); // failure on this line, db undefined
}
}
the error that I am getting is either this (error1):
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Public_homepage::$sites
Filename: controllers/public_homepage.php
Line Number: 15
Fatal error: Call to a member function get() on a non-object in /var/www/businessbuilderapp.com/public_html/application/controllers/public_homepage.php on line 15
or this (error2):
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Businessbuilder::$db
Filename: core/Model.php
Line Number: 50
Fatal error: Call to a member function query() on a non-object in /var/www/businessbuilderapp.com/public_html/application/models/bba_model.php on line 25
My theory as to why I am getting these errors is because the instance of the object is different than the one that loaded the model and libraries. What's odd about that though is that arrays are carried over, but not objects. So in the core Loader.php of codeigniter array $_ci_models is populated with models that are not loaded in the Public_homepage class
Also what might help you is that from the first pass through the businessbuilder class, I am able to load and use the modules successfully, but when Public_homepage is called, that's when things start to fail.
What makes this confusing is that I'm trying to figure out 2 errors with one question which is probably my mistake. Here is a description of when I get the errors:
Error1:
When I run the code as is, I cannot call the sites property.
Error2:
When I change the
call_user_func_array(array(&$CI, $function), array_slice($RTR->uri->rsegments, 2));
to
eval($class . "->" . $function);
I understand that this is really confusing, especially when I explain it, but if you need more info, please let me know. Also note that the Public_homepage looks like that because I am testing. There's no need to dump more useless lines if the error can be produced with minimal code.
Update
After reading some of the answers, I realized that I didn't explain the code. What this code does is that it allows me to store different urls inside a database, but all the urls stored there can call the same page even though they are different. I guess an exact example would be changing the slug on wordpress.
What happens is that the businessbuilder class is set to accept ALL requests to the server. When it hits the businessbuilder class, it will access the database, find out what sub url you are using, find the real controller that the user is looking for, and access that controller.
So after lots of searching, I think I have a workaround. The issue what what I thought with the instance. After diving into the framework I realized that it is storing the instance into as static var, private static $instance. I modified the constructor to not overwrite if that var has been populated. On top of that, since there were some oddities still with the loading, for some reason objects would be marked as loaded but in reality were not, I had to add a new var to the controller, protected $ci_instance. In the end, I modified the CI_Controller to look like the following:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 5.1.6 or newer
*
* #package CodeIgniter
* #author ExpressionEngine Dev Team
* #copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* #license http://codeigniter.com/user_guide/license.html
* #link http://codeigniter.com
* #since Version 1.0
* #filesource
*/
// ------------------------------------------------------------------------
/**
* CodeIgniter Application Controller Class
*
* This class object is the super class that every library in
* CodeIgniter will be assigned to.
*
* #package CodeIgniter
* #subpackage Libraries
* #category Libraries
* #author ExpressionEngine Dev Team
* #link http://codeigniter.com/user_guide/general/controllers.html
*/
class CI_Controller {
private static $instance;
protected $ci_instance; // line added
/**
* Constructor
*/
public function __construct()
{
if(self::$instance == null) // line added
self::$instance =& $this;
$this->ci_instance =& get_instance(); // line added
// Assign all the class objects that were instantiated by the
// bootstrap file (CodeIgniter.php) to local class variables
// so that CI can run as one big super object.
foreach (is_loaded() as $var => $class)
{
$this->$var =& load_class($class);
}
$this->load =& load_class('Loader', 'core');
$this->load->_base_classes =& is_loaded();
$this->load->_ci_autoloader();
log_message('debug', "Controller Class Initialized");
}
public static function &get_instance()
{
return self::$instance;
}
}
// END Controller class
/* End of file Controller.php */
/* Location: ./system/core/Controller.php */
The only issue so far is that I cannot do $this->load->model("some_model");. Instead I have to use $this->ci_instance->load->model("some_model"); and everything will stem from there. I don't really care about the extra var, but what I don't like is modifying out of box solutions because it increases the complexity to do an upgrade.
for now I've marked this as an answer because it is what "I" have chosen to use as my solution, but I am still opened to a better solution than the one I am using. An exact description of what needs to be solved is as follows:
Copy all loaded properties from one instance to another. Basically do a merger of two instances if possible.
If someone can answer that with a better solution than mine, preferably without modifying the codeigniter core, I'd gladly change my answer because I am not happy with my solution because I don't know what effects I might encounter later on during development.
In your application/autoload.php set codeigniter to load database class.
$autoload['libraries'] = array('database', 'otherlibrary', 'otherlibrary2');
It must be all you need to solve your problem.
if u using HMVC just using
Class Models extends MX_Loader{
function getUser($username){
$sql="SELECT
*
FROM
user
WHERE username = ? "
return $this->db->query($sql,array($username))->row();
}
}

Resources