Where should I put the function that loads a model and Display a view but that is not accessible from the URL. I mean, I need to write a function that should call from the view and this function displays a menu list.
function displayMenu () {
$menu = $this->model->getMenuResults();
$this->load->view( 'ViewResults', $menu);
}
Should I write this as a private function in the main controller?
You can use private functions in codeigniter controller
private function _displayMenu()
{
$menu = $this->model->getMenuResults();
$this->load->view( 'ViewResults', $menu);
}
Straight from documentation
Private Functions
In some cases you may want certain functions hidden from public access. To make a function private, simply add an underscore as the name prefix and it will not be served via a URL request. For example, if you were to have a function like this:
private function _utility()
{
// some code
}
Trying to access it via the URL, like this, will not work:
example.com/index.php/blog/_utility/
For more details go to http://ellislab.com/codeigniter/user-guide/general/controllers.html#private
Put it in one of your helper functions like this
function displayMenu () {
$CI = &get_instance();
//choose whichever is appropriate
//option 1
//if your model is globally loaded then simply call the model like this
//$menu = $CI->loadedmodel->getMenuResults();
// option 2 otherwise load the model here
//$CI->load->model('model_name');
//$menu = $CI->model_name->getMenuResults();
$CI->load->view( 'ViewResults', $menu);
}
Related
I'm reading opencart php source code, and I can't figure this out.
Please take a look at function rewrite() at "$url = $rewrite->rewrite($url);"
<?php
class Url {
private $url;
private $rewrite = array();
public function link($route, $args = '', $connection = 'NONSSL') {
....
foreach ($this->rewrite as $rewrite) {
$url = $rewrite->rewrite($url);
}
return $url;
}
public function addRewrite($rewrite) {
$this->rewrite[] = $rewrite;
}
}
?>
Why above code doesn't generate error ?
The rewrite function is not defined in class Url, and class Url doesn't extend anybody ??
But then I track deeper, it seems that function rewrite is at seo_url class.
class ControllerCommonSeoUrl extends Controller {
// Add rewrite to url class
if ($this->config->get('config_seo_url')) {
$this->url->addRewrite($this);
}
...
public function rewrite($link) {
if ($this->config->get('config_seo_url')) {
$url_data = parse_url(str_replace('&', '&', $link));
....
Why ? I don't see any connection between 'Url' and this 'ControllerCommonSeoUrl' yet. Am I missing some concept here ? What I should do to understand these codes ? Need little guidance here.
foreach ($this->rewrite as $rewrite) {
Iterates over whatever values in:
private $rewrite = array();
And maybe that Url->rewrite array contains an instance of ControllerCommonSeoUrl, that would explain why $rewrite->rewrite() calls ControllerCommonSeoUrl->rewrite().
Also, you'd do yourself a favor by trying to learn to use a debugger :)
check if the controller is loading any model in the script if so , the model method can be simply accessed inside the script which might be the case with your script as $this->rewrite.
The Url class is a generic class that can have multiple URL rewrite method's called, making it possible for people to change the URL rewriting code. Triggering the SEO URL code to add it to the Url class is done in the index.php file by the following
// SEO URL's
$controller->addPreAction(new Action('common/seo_url'));
When that Action is executed, the ControllerCommonSeoUrl executed the index() method, and as with the code you provided, it checks if SEO URL's are active in the settings. If they are, then the current class is added to the array of rewrite's in the Url class. Then whenever someone calls $this->url->link() each of the rewrite classes have their rewrite() method called and the subsequent URL is passed back
I am developing a CRM for our agency in Codeigniter and I have a question that I can't seem to find a solid answer on. If I have a task that I do on the majority of methods in a controller, is there any way to define that action only once? For instance...
Every view call gets passed the $data variable, like so...
$this->load->view('templates/template.php', $data);
So if I am doing something like getting the admins information in every function of the controller, how can i tell it to do that action ONE time and pass it to all my functions.
Like this...
$data['admin'] = $this->Crm_model->get_admin();
I've tried putting that ^ in the constructor and it doesn't work. Any ideas?
If you do:
$data['admin'] = $this->Crm_model->get_admin();
in the constructor, $data's scope is limited to the constructor. You need to create it as a class property so it is scoped to the entire class. Do this instead
$this->data['admin'] = $this->Crm_model->get_admin();
in the constructor, and then in other methods, you can access the array by doing $this->data
Here's an example:
class Foobar extends CI_Controller {
public function __construct() {
$this->data['foo'] = "bar";
}
public function index() {
// use the class property data here to add more info to it
$this->data['hello'] = "world";
// now pass this to the view
$this->load->view('myView', $this->data);
// myView will receive both $foo and $hello
}
}
Basically everything works if I hard code the URL in my Ajax_Controller, but I want it to access the URL from the CMS field I created.
Thanks in advance. (please ignore when I don't close my braces - just trying to copy / paste efficiently)
In /mysite/_config.php I created a custom config:
Object::add_extension('SiteConfig', 'CustomSiteConfig');
In /mysite/code/CustomSiteConfig.php I added a field where I'll store a URL:
class CustomSiteConfig extends DataObjectDecorator {
function extraStatics() {
return array(
'db' => array(
'COJsonPath' => 'Text'
)
);
}
public function updateCMSFields(FieldSet &$fields) {
$fields->addFieldToTab("Root.CO", new TextField("COJsonPath", "CO JSON URL"));
}
public function getCOJsonPath(){
return $SiteConfig.COJsonPath;
}
This successfully creates a tab in the main parent in the CMS called "CO" and a field named "CO JSON URL". I logged into my CMS and saved http://api.localhost/mymethod/ to that field.
Now I have created an Ajax page type to facilitate running Ajax commands without letting the web site user find where my APIs are, and because jQuery Ajax no likey XSS (cross site scripting).
In /mysite/code/Ajax.php:
class Ajax extends Page {
static $db = array(
);
static $has_one = array(
);
function getCMSFields()
{
$fields = parent::getCMSFields();
return $fields;
}
}
class Ajax_Controller extends Page_Controller {
public function getCO()
{
$buffer = self::createHttpRequest("http://api.localhost/mymethod/");
//$buffer = self::createHttpRequest($CustomSiteConfig::getCOJsonPath());
return $buffer;
}
This code works, but when I try to execute my createHttpRequest() with the line you see commented out, it fails. I know my syntax is wrong, I just can't figure out what it should be. Thanks for helping - I've done this before I just can't figure it out - its Friday.
I spotted several syntax errors in your code:
public function getCOJsonPath(){
return $SiteConfig.COJsonPath;
}
should be:
public function getCOJsonPath(){
return $this->owner->COJsonPath;
}
1) $SiteConfig is never defined at that point.
2) usually you would use $this, but in your case you are inside a DataObjectDecorator, so you have to use $this->owner
3) you can not use . to access properties of an object, in php you have to use ->
moving on to class Ajax_Controller, inside getCO there are the following errors:
1) $CustomSiteConfig is not defined, therefore can not be used
2) getCOJsonPath is not a static function, but you try to call it as static (again you have to use ->
so, the code should look something like this:
public function getCO() {
$siteConfig = SiteConfig::current_site_config();
$buffer = self::createHttpRequest($siteConfig->getCOJsonPath());
return $buffer;
}
that should work, but there is another think that could be improved.
As I understand it, you are creating an ajax page, which you then create once in the CMS and tell your website content authors never to touch the ajax page?
This is quiet ugly, and there are several nice ways to do what you want to do.
Here is how I would create an Ajax controller:
_config.php
// tell SilverStripe what URL your AjaxController should have,
// here we set it to AjaxController::$URLSegment which is 'myAjaxController'
// so the url to the controller is mysite.com/myAjaxController
Director::addRules(100, array(
AjaxController::$URLSegment => 'AjaxController',
));
AjaxController.php
<?php
class EventAssetsController extends Controller {
public static $URLSegment = 'myAjaxController';
// tell SilverStripe what URL should call what function (action)
// for example, mysite.com/myAjaxController/foo should call the function foo
public static $url_handlers = array(
'foo' => 'foo',
'bar/$ID/$OtherID' => 'bar',
'co' => 'getCO'
);
public function Link($action = null) {
// this function is just a helper, in case you evern need $this->Link()
return Controller::join_links(self::$URLSegment, $action);
}
public function AbsoluteLink($action = null) {
return Director::absoluteURL($this->Link($action));
}
public function foo(SS_HTTPRequest $request) {
// do something here
// this method is an action, the url to this action is:
// mysite.com/myAjaxController/foo
}
public function bar(SS_HTTPRequest $request) {
// do something here
// this method is an action, the url to this action is:
// mysite.com/myAjaxController/bar
// you notice that the $url_handlers has "bar/$ID/$OtherID",
// that means you cann call mysite.com/myAjaxController/bar/21/42
// and silverstripe will make 21 the ID, and 42 the OtherID
// you can access ID and OtherID like this:
// $ID = $request->param('ID'); // which is 21
// $OtherID = $request->param('OtherID'); // which is 42
}
public function getCO() {
// this method is an action, the url to this action is:
// mysite.com/myAjaxController/co
$siteConfig = SiteConfig::current_site_config();
$buffer = self::createHttpRequest($siteConfig->getCOJsonPath());
return $buffer;
}
}
I have a class that defines new meta boxes in an admin area of a web site. Each new box requires quite a lot of arguments, so the defining of each new object is kept in a separate function.
function my_metabox(){
$args = array(/*the args*/);
$metabox = new MetaBox($args);
}
And then I have a function, positioned where I need the boxes loaded, to load all of the metaboxes at once.
function load_metaboxes(){
my_metabox();
my_other_boxes();
etc_etc();
}
The problem mostly is having to manually alert the load_metaboxes() function whenever I create a new box, is there a better way to structure this?
Maybe you can use something like this:
//declaring my functions
function test_funct_1() { echo 'test'; return true; }
function test_funct_2() { return true; }
function test_funct_3() { return true; }
function test_funct_4() { return true; }
//get all function declared
$func = get_defined_functions();
//show only functions declared by user (you)
print_r($func['user']);
//call a individual function
$func['user'][0]();
use php autload magin method
here is the documentation
http://php.net/manual/en/language.oop5.autoload.php
in your class create a method name __autoload and call all the function in it so when you make an instance of the class the function called in __autoload will automatically loaded
I don't have alot of experience with OOP programming in PHP, and my search has given no result but solutions to direct methods. What I need is this:
// URL Decides which controller method to load
$page = $_GET['page'];
// I want to load the correct controller method here
$this->$page();
// A method
public function home(){}
// Another method
public function about(){}
// e.g. ?page=home would call the home() method
EDIT: I've tried several of the suggestions, but what I get is a memory overload error message. Here is my full code:
<?php
class Controller {
// Defines variables
public $load;
public $model;
public function __construct() {
// Instantiates necessary classes
$this->load = new Load();
$this->model = new Model();
if (isset($_GET['page'])) {
$page = $_GET['page'];
$fc = new FrontController; // This is what crashes apparently, tried with and without ();
}
}
}
If I understand your question correctly, you'd probably want something more like this:
class FrontController {
public function home(){ /* ... */ }
public function about(){ /* ... */ }
}
$page = $_GET['page'];
$fc = new FrontController;
if( method_exists( $fc, $page ) ) {
$fc->$page();
} else {
/* method doesn't exist, handle your error */
}
Is this what you're looking for? The page will look at the incoming $_GET['page'] variable, and check to see whether your FrontController class has a method named $_GET['page']. If so, it will be called; otherwise, you'll need to do something else about the error.
You can call dynamic properties and methods using something like this:
$this->{$page}();
Use a class.
Class URLMethods {
public function home(){ ... }
public function about(){ ... }
}
$requestedPage = $_GET['page'];
$foo = new URLMethods();
$foo->$requestedPage();
You can achieve this by using call_user_func. See also How do I dynamically invoke a class method in PHP?
I think you'd like also to append another string to the callable functions like this:
public function homeAction(){}
in order to prevent a hacker to call methods that you probably don't want to be.