how to create a method on the fly in ci - php

I'm writing a control panel for my image site. I have a controller called category which looks like this:
class category extends ci_controller
{
function index(){}// the default and when it called it returns all categories
function edit(){}
function delete(){}
function get_posts($id)//to get all the posts associated with submitted category name
{
}
}
What I need is when I call http://mysite/category/category_name I get all the posts without having to call the get_posts() method having to call it from the url.
I want to do it without using the .haccess file or route.
Is there a way to create a method on the fly in CodeIgniter?

function index(){
$category = $this->uri->segment(2);
if($category)
{
get_posts($category); // you need to get id in there or before.
}
// handle view stuff here
}
The way I read your request is that you want index to handle everything based on whether or not there is a category in a uri segment. You COULD do it that way but really, why would you?
It is illogical to insist on NOT using a normal feature of a framework without explaining exactly why you don't want to. If you have access to this controller, you have access to routes. So why don't you want to use them?
EDIT
$route['category/:any'] = "category/get_posts";
That WOULD send edit and delete to get_posts, but you could also just define those above the category route
$route['category/edit/:num'] = "category/edit";
$route['category/delete/:num'] = "category/delete";
$route['category/:any'] = "category/get_posts";
That would resolve for the edit and delete before the category fetch. Since you only have 2 methods that conflict then this shouldn't really be that much of a concern.

To create method on the fly yii is the best among PHP framework.Quite simple and powerful with Gii & CRUD
http://www.yiiframework.com/doc/guide/1.1/en/quickstart.first-app
But I am a big CI fan not Yii. yii is also cool though.
but Codeigniter has an alternative , web solution.
http://formigniter.org/ here.

Related

Having an "edit" controller to deal with user editing? Does this design make sense?

Here is the flow:
User creates a text based post.
User edits a text based post (an edit page with the post info is displayed)
User submits the changes to the post (a request sent to the post controller)
Now, if I have MULTIPLE types of posts, I have to check in steps 2 and 3 that the user is indeed updating the RIGHT type of post because someone could very well alter the URL to edit a post of type A when it's really of type B. This leads to a lot of redundant code, such as ...
if(user is indeed the editor && the post type is correct) show the edit page
I think it would make a lot of sense to have an EDIT controller that does all the verification needed in the constructor (or maybe a base class?), and then calls the method. Have you encountered similar issues like this - and if not, does this make any design sense?
CodeIgniter is an MVC. That means that your controllers serve as an intermediate between your models (your data), and your view (front-end). "Edit" is an action that you do to objects, like data. Data objects should be organized within a controller, which calls the actual edit functions from the model.
I'm assuming you have a Post controller. At its core, it should have basic CRUD functions, like adding and editing posts. It should look something like this:
class Post extends CI_Controller
{
function __construct()
{
parent::__construct();
}
function index()
{
// List all posts, perhaps?
}
function add()
{
// Add a post
}
function edit($post_id)
{
// Edit a post
}
function view($post_id)
{
// View a post
}
}
That will give you the following pages:
http://example.com/post
http://example.com/post/add
http://example.com/post/view/1
http://example.com/post/edit/1
Checking for user permissions is its own chapter. If you are using a library like Tank Auth, you can check permissions like so:
if ($this->tank_auth->is_logged_in()) {
// Do stuff
}
That should go at the beginning of each function - or in the __construct(), if you want to DRY it up completely.
Good luck.

Form as HMVC widget

Is this the right way to create a form widget in FuelPHP?
class Controller_Widget extends Controller
{
public function action_show()
{
if (Request::is_hmvc())
{
// show form widget
}
else
{
// process form
}
}
}
The form action calls the same function to process, but where will it redirect to after? how will it show validation errors?
Note: The widget should not be accessible through the URL; the form should not display itself if accessed directly through the URL.
EDIT:
Found a similar problem in CodeIgniter HMVC and dynamic widgets but this is from 3 years ago. Maybe the FuelPHP guys have found a better way to do this.
This seems like a weird method, a method that is called show but handles both showing and manipulating data? A method called "show" (or get, fetch, read, etc) shouldn't do any editing, it's name expressly seems to imply that it's a read-only operation.
But also how it proceeds seems off. Its read-operation is HMVC only but its manipulation operation is non-HMVC only? That's really a wrong way to determine what the method should do, whether or not it is HMVC should have no baring on what it does.
In your case I'd split this up into 2 methods: one for retrieval (show()) and another for manipulation (edit() for example). Whether you want to make these HMVC only is up to you. There's more ways than one to solve that, I'd go with:
if ( ! Request::is_hmvc())
{
throw new Exception('Only HMVC access allowed.');
}
Or make it impossible to route to the method by rerouting it in your routes.php config file and then using the HMVC routing overwrite as discussed here: https://stackoverflow.com/a/9957367/727225

CakePHP: Get model instance by url string

I have a CakePHP website and navigaton links are stored in database. What i want is for some navigation entries to call custom function which will return some additional, dynamic data about the link: I want to add a count of articles for link "Vacancies". I could call a function on a model that would return total count. This link is to be rendered on every page.
So i need to get appropriate models instance, but not for the current request, but the request where url points to.
So basically i have url "/en/vacancies". I can get controller name by:
$urlInfo = Router::parse("/en/vacancies");
$controllerName = $urlInfo['controller'];
What would be the reliable way to do that?
Any other solutions for the problem are welcome.
Assuming you have the method to gather the navigation link data in a Model.
App::import('Controller', $controllerName);
$controller = new $controllerName;
$controller->loadModel('YourModel');
$yourModel = $controller->YourModel;
$yourData = $yourModel->your_method();
There are a variety of other ways to do this. But, without knowing more about where you're actually going to be calling this function I can't really provide anymore suggestions.

CodeIgniter load controller from view

Is there a way to load a controller from a view ?
Here is what i am affter..
I want to use one view multiple times, but this view is being loaded by separate controller that gives the view, information from the db.So becouse of that information from the model i can't just set $this-load->view(); and etc. Is there a way to do this thing, or it has a better way ?
I think a lot of sites face similar challenges, including one I'm working on that loads the same db content into the sidebar on almost every page in the site. I implemented this with the combination of a library and a helper:
Put the data logic into the library (mine is named common.php). In addition to interfacing with the database, you may want the library to store the data in a local variable in case you want to reference it multiple times on a single load.public function get_total_items()
{
if ($this->_total_items === NULL)
{
$row = $this->ci->db->query("SELECT COUNT(*) FROM items")->row();
$this->_total_items = $row[0];
}
return $this->_total_items;
}
Create a helper to load the library. (Don't load libraries within a view!) I have MY_text_helper that loads the library and returns the data:function total_items()
{
$CI =& get_instance();
return $CI->common->get_total_items();
}
Call the helper function from within the view.<p> Total items: <?php echo total_items(); ?> </p>
Simply put, you can't and shouldn't load a controller from a view. That sad, I understand your frustration because you want to re-use the model-pulling/acting logic in the controller across multiples views.
There are various ways of doing this;
Re-use the models. Your models should be very simple to select data from, and should be sleek, but if you're doing the same thing over and over it does seem stupid. In which case...
Use a controller as a "main container" and extend upon it from any logic you need. So your basically using the controller as a template, which pulls data down from the model, loads the appropriate view.
MVC doesn't work that way ... Just re-use the model - that's why it's separate from the controller. If that doesn't fit your needs, you should probably implement a library that does the logic.
I would use a library.
That way you can wrap up the data retrieval in a reusable package that you can call from any controller you like.
just do this
if you controller named controller1
put a link in view just like that
http://your-site.com/index.php/controller1/
if you want specific function add it to your url
http://your-site.com/index.php/controller1/myfunction
that's it

codeigniter routing

I am currently working on CMS for a client, and I am going to be using Codeigniter to build on top of, it is only a quick project so I am not looking for a robust solution.
To create pages, I am getting to save the page details and the pull the correct page, based on the slug matching the slug in the mysql table.
My question is however, for this to work, I have to pass this slug from the URL the controller then to the model, this means that I also have too have the controller in the URL which I do not want is it possible to remove the controller from the URL with routes?
so
/page/our-story
becomes
/our-story
Is this possible
I would recommend to do it this way.
Let's say that you have : controller "page" / Method "show"
$route['page/show/:any'] = "$1";
or method is index which I don't recommend, and if you have something like news, add the following.
$route['news/show/:any'] = "news/$1";
That's it.
Yes, certainly. I just recently built a Codeigniter driven CMS myself. The whole purpose of routes is to change how your urls look and function. It helps you break away from the controller/function/argument/argument paradigm and lets you choose how you want your url's to look like.
Create a pages controller in your controllers directory
Place a _remap function inside of it to catch all requests to the controller
If you are using the latest version of CI 2.0 from Bitbucket, then in your routes.php file you can put this at the bottom of the file: $routes['404_override'] = "pages"; and then all calls to controllers that don't exist will be sent to your controller and you then can check for the presence of URL chunks. You should also make pages your default controller value as well.
See my answer for a similar question here from a few months back for example code and working code that I use in my Codeigniter CMS.
Here's the code I used in a recent project to achieve this. I borrowed it from somewhere; can't remember where.
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
Then, my index function is where you would put your page function.

Categories