With Codeigniter, what's the difference if I wanted to set a method to private? - codeigniter

With callback functions that are within the same class, I can't set the following.
private function check_valid_image
{
...
}
I can get it to work if I do the following.
function _check_valid_image
{
...
}
By placing an underscore in front of the method name, is that the same as placing the word private in front?

It's a convention used with the form validation class for callbacks. It also makes that method not callable via the URL segments.
That being said, it is not the equivalent of making a method private, which has implications in how code can be run outside of the class.

Related

Yii2 virtual attribute getter had to change to function call

I'm new to OOP and Yii2. I have a function in Model:
public function getDatRev() {
if ($this->rev) {
return $this->rev;
} else {
return $this->datum;
}
}
in the View until now I have used it like this:
$model->datRev;
and it would return the correct value. Now I don't know what has changed, maybe I was also updated the framework, but the old construct doesn't work anymore, and in order to make it work I have to change it to:
$model->getDatRev();
Can you please explain to me why that is?
When you try get property the Yii2 calls magic method __get (). Return value is depend from implementation of this method in parent class. Yii2 can check if this property exist in some container, or if exist getter of this property.
In your case seems like you don't call parent's method __get(). This may have happened because you override __get() method or initialized this property.
Your class needs to extend yii\base\Object (directly or not) in order to use short property syntax ($model->abc instead of $model->getAbc()). Magic method __get() #Timur mentioned is defined there and further extended in yii\base\Component class.

Identifying the remapped function in a CodeIgniter controller

My controller has a remap function that redirects routed calls for its index method to either methodA or methodB.
From within each of these two methods, an external class instance makes a call to it's own methods, something like this:
methodA(){
$newClass = new newClass();
$newClass->doStuff();
}
in doStuff(), the code does stuff contingent to what segment was referenced. Essentially, I may get data like this
doStuff(){
$data = $assets[$this->ci->router->fetch_class()][$this->ci->router->fetch_method()];
}
But this will fail since $this->ci->router->fetch_method() will return index, not the remapped method. I need to be able to retrieve the remapped method for the correct data corresponding to the remapped method.
I can easily do this by passing the name of the invoking function to this method call, but is there a more CodeIgniter way of doing this ? i.e: Getting the remapped method to which the router method was mapped onto ?
If not, alternate solutions ?

Alternative to using codeigniter libraries for additional classes

I have an existing controller (classA) which needs to use a new helper class (classB). Typically I would place classB into a library and do
$this->load->library('classb');
$this->classb->method();
However, I've run into a problem where I am defining const's in my classB which are required by the constructor
classB {
const MYDEFINE = 1;
...
}
The problem with this approach is the definition of MYDEFINE is NOT available until I load the library, but I need to create the $params array with the arguments to send the classB constructor. So I get a case of chicken vs. egg
$params = array();
$params['open_mode'] = classB::MYDEFINE;
$instance = $this->load->library('classB', $params);
I've been able to solve this problem by not using a library - and instead using a #include_once('classB') in my classA controller which is working fine. The file classB.php is therefore stored in the controllers directory.
I'm wondering if others have run across this problem and how they might have solved it (other than by decaaring the consts elsewhere). I looked at a post by PhilSurgeon (http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-Base-Classes-Keeping-it-DRY) on an alternative method but its not quite the right fit for this problem (at least I don't think so).
I'm unclear why you would declare a constant, and then load it into the config when you initialize the class...that makes no sense, is why you have the chicken-and-egg issue
I would set things up roughly as:
private $myvar = 'My Constant Value';
function __construct() ... etc
and then you can access it using:
$this->myvar
anywhere in your library class, including the construct if you want to change it via your config
EDIT: You could still use a constant is that is more appropriate, but then pass it to the $this->myvar in your construct() as a above. The point is, your Constant should never be worked with outside of the class
how about creating a bootstrap library
like
include 'path/to/class/b';
class Init_class_b Extends class_b
{
function __construct($params)
{
// handle the variables here
parent::__construct();
}
}
then:
$this->load->library('Init_class_b',$params_for_construct);
$this->Init_class_b->method()

Add method to be available in all Views

I would like to have a method available to all Views in my app.
I would like to be able to make calls like this:
<span>${ getDynamicText() }</span>
The most obvious ways (to me) to implement this are:
Call the method in the controller and and pass it to the View.
Make the method static on some Util class and call it from the code ${ UtilClass.getDynamicText() }
Using meta programming to somehow make the method available to all Views.
The benefit of #3 is that the change would only have to be made in one place. #1 would have to be made in each controller action; and #2 would need an import on every View page which wants to use the method.
So is there a way to add a method to be available to all views in my app?
I have to admit I don't know in a lot of detail how .gsp files are processed behind-the-scenes so maybe they don't have a corresponding class and therefore can't be manipulated in this way. Links to good articles/docs will get extra good karma.
GSPs are compiled into classes that extend org.codehaus.groovy.grails.web.pages.GroovyPage, so you can add methods to that metaclass and they'll be available to all GSPs. The best place to do this is in BootStrap.groovy (or in a plugin's doWithDynamicMethods closure):
import org.codehaus.groovy.grails.web.pages.GroovyPage
class BootStrap {
def init = { servletContext ->
GroovyPage.metaClass.getDynamicText = { ... }
}
}
The recommended way to reuse functionality across GSPs is to define it as a tag, e.g.
class MyTagLib {
static namespace = 'my'
def dynamicText = {attrs ->
out << 'not very dynamic'
}
}
You can then call this tag in a GSP using:
<my:dynamicText/>
4th way: make a class/service that have method '.getDynamicText' and put it's intance into request at before filter ( request.setAttribute('x', myDynamicTextGeneratorObject) )
Now you can use x.dynamicText in any GSP
This is how I would do it:
Add a new class to your controllers folder containing your method
Do a grails install-templates
Navigate to the templates: \src\templatesscaffolding
Add the extends part to the controller template: class ${className}Controller extends NewController
re-generate your controllers
You can now use the method in every class and gsp.

Wrapper class does not save to database when set

I have a wrapper class that is meant to get and set code from a property in one of my dbml's partial classes. The reason for the wrapper is for a specialized get, which pre-formats the value. Here's what the wrapper looks like (NOTE: this is not the actual code, but represents everything but the formatting accurately):
partial class Class1
{
public string PropertyFormatted
{
get
{
var ret = Property.Substring(1);
return ret;
}
set { Property = value; }
}
}
This wrapper is bound using Bind() in a formview for the edit page. For some reason, the wrapper's value is set twice on update and the second time through the value is re-assigned its original value (causing the property to remain, ultimately, unchanged). However, when the wrapper is replaced with the property itself, there is no problem with saving to the database.
Any ideas what may be the cause of this?
The dbContext should be automatically detecting changes via this method:
http://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbchangetracker.detectchanges(v=vs.103).aspx
You may have inadvertently disable auto detect changes or something of the like. Try manually calling the method and see if that makes a difference.
Good luck!

Resources