I used this tutorial http://www.yiiframework.com/wiki/208/how-to-use-an-application-behavior-to-maintain-runtime-configuration/ to change language. But I ran into problem that $_Post['lang'] variable is not being reset and every time I try to refresh the page, It gives me form resubmition dialog, which I don't want to have. But I don't know where and how to use redirect, since it doesnt work in behaiours class. How can I prevent this form resubmition?
Edit: I found an ugly solution, to put this code in every view file that I have
<?php
$this->renderPartial('//lang/_refresh', array())
?>
But It involed repeating same code alot and I am sure there is a better solution out there (probably to place a refresh function in the right place)
Found a solution, all you need is to add a beforeAction to components/Controller since all added controllers extend it. The problem was I didn't know that. Here is the function that works so that I dont have to rewrite the code.
protected function beforeAction()
{
if (isset($_POST['lang'])) {
$this->refresh();
}
return true;
}
Related
I'm posting this after my hair has been ripped out, ran out of rum, and tried everything I can find on google. I've been developing a site using codeigniter which makes use of templates. I've built the backend first and all is working properly there. So now i've started on getting the front end working which is where I'm hitting the issue.
I've created a controller called pages.php which is going to parse the uri string of the current page, use my library to get the page data from the database, then display it. My pages are all created through an editor on the back end and stored in the database.
So here's the pages controller
class Pages extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->library("pages");
}
public function display_page()
{
$page_slug = $this->uri->segment(1);
$data["joes"] = "Here's joes first variable";
$this->pages->get_page($page_slug);
}
}
and here's the error message i get when i hit my url like this demo.mydomain.com/joes-test
and here is how my routes are set up. $route['(:any)'] = 'pages/display_page';
My Pages.php library works perfect on the back end but it's a large file. I've only posted the get_page function below. If you need to see everything let me know. But i dont believe the issue has anything to do with the library itself.
public function get_page($slug){
$objPages = new pages();
$objPages->get_object('slug="'.$slug.'"');
return $objPages;
}
[EDIT] If i place the following inside my homepage controller it works. But the calling function needs to be inside the library.
$this->load->library('pages');
$the_page = $this->pages->get_page("joes-test");
I want to call $this->get_object("joes-test") but this doesn't work. get_object() is an inherited function inside the library.
Now oddly enough. The code i put above will NOT work if i do the exact same thing inside the pages controller
any help leading to a solution would be awesome. I'm under a time crunch and pay to get some assistance. Thanks in advance.
No you can't use the same name with controller and library. please choose another name. for example Mypages for you controller name.
change your routes
$route['(:any)'] = 'mypages/display_page';
then call your controller.
http://demo.mydomain.com/joes-test
I think there nothing wrong with library uri, because as codeigniter official website say: This class is initialized automatically by the system so there is no need to do it manually.
I don't know about lib pages, but how about use
$this->load->view(<file-html>);
and if you want to passing data in variable, you can add variable like this
$this->load->view(<file-html>, $data);
Hope this help, Cheers
I'm attempting to create a custom display in yii2 framework using this code in my site controller:
/******/
public function actionChartDisplay()
{
return $this->render('chartDisplay');
}
for testing purposes I pasted the form name in my actionAbout function as a parameter to the render function in it. It worked with this:
public function actionAbout()
{
return $this->render('chartDisplay');
}
But I need to create many custom views in yii2 and this won't be a solution.
This is the error I get
I'm curious as to why it is. Since I was following this tutorial and came across this weird behaviour.
My 'chartDisplay.php' file is merely a "hello world" that does work with the action about function.
in yii2, the controllers and actions with multiple words, that are marked by capital letters are divided by - in your request, so in your case the route would be some/chart-display
Apparently as #SmartCoder pointed out it was an error on how Yii2 Handles the action functions in its controller however I didn't mark his answer as the solution right away because implementing it resulted in an error. So aside from that I'm posting the way I solved it.
So instead of using chart-display I simply changed it for "charts" like this:
public function actionCharts(){
return $this->render('charts');
}
Changed the name of my file so it fits to charts.php and it worked.
I have an element called userbar on every page - it tells the user if he/she is logged in or not. I created this element and echoed it in default.ctp:
<?php echo $this->element('userbar', array('text' => 'You are not logged in.')); ?>
Now it shows on every page. However, I can't find anywhere how to change this text. For e.g., I would like to access this element from some controller and change it. How?
You set a view variable and then use that.
<?php
class MyController extends AppController
{
function myaction () {
$this->set ('my_var', 'You are not logged in');
}
}
?>
And then in the view:
<?php echo $this->element ('userbar', array ('text' => $my_var)); ?>
Considering this is something you'd do on every page request its best to put it in the AppController::beforeFilter().
There are other ways to do this. But if you render the element in the controller you still need to set a view variable and echo that in the view.
Hope this helps.
I think that vanneto did a good job on answering the question very specifically. But based on my opinion what happens here is a design flaw. That's why I add this answer to give you another option on how to approach this question. Because I see this kind of solutions and on the longer run they cause issues.
The case is a logged-in or logged-out text.
Let's say that you use the Auth component:
http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
We will start at the controller, likely you have something like this in the AppController:
public function beforeFilter() {
parent::beforeFilter();
$this->set('userIsLoggedIn', AuthComponent:: loggedIn());
$this->set('loggedInUser', AuthComponent::user());
}
So what this does: At every request it sends the logged in user to the view. Now you could say the controller could have an if statement to detect which text should be sent out but it's not really necessary.
In you element you could do that also.
So in your element put something like:
if($userIsLoggedIn) {
echo 'User is logged in.';
}else{
echo 'You are not logged in!';
}
Generally we move a bit more to helper to implement this kind of logic because they are classes which have more options for well styled coding. But it's also doable simply with an element.
So now you got the texts right. Then you get to the point: Does a static text belong to the element? No, it does not. So what would improve it is to implement it like:
if($userIsLoggedIn) {
echo __('User is logged in');
}else{
echo __('User is not logged in');
}
That way you can put the static texts into your .po files. If you don't know what they are:
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
The element can now be used also if your site becomes multi language for example. Or you could let your textwriter edit the texts without touching the source code.
As you see it's a different approach but I think it will give you more clear code. It decoupled the code, the controller does his task, the element does his task and the text is also seperated out because it doesn't belong hardcoded in the views.
In terms of code it's not much more so I would strongly advise some solution which looks like this. Could also be done with a helper.
Some sources on this kind of approaches:
http://en.wikipedia.org/wiki/Object-oriented_programming#Decoupling
http://en.wikipedia.org/wiki/Single_responsibility_principle
Situation: only main page is accessible by default, all other pages needs a logged in user. When a module is loaded without user, a login template should be displayed, and no module. In other words, the $sf_content must be emptied in layout.php which is not 100% ok since there is logic in the layout. Is there elegant way for that? I dont think a helper is OK either....
Check out security filters, this is one standard way security is designed in symfony.
You even can implement your own SecurityFilter class with the functionality you want.
http://symfony.com/legacy/doc/reference/1_4/en/12-Filters#chapter_12_security
It is done by default for you by the sfBasicSecurityFilter filter. You just need a good configuration. Read this part of the Jobeet tutorial. You should use sfDoctrineGuardPlugin (or sfGuardPlugin if you using propell) for user authentication.
To complete my comments above: There are different ways to override the layout. You could use the methods:
setLayout($name)
//or using foward, which forwards current action to a new one (without browser redirection)
forward($module, $action);
inside your action class. In case you wand to modify the layout inside a filter, you can use something simular to this:
class yourFilter extends sfFilter {
public function execute($filterChain) {
if($yourConditionForOverrideTheDefaultLayout) {
//here the syntax to change the layout from the filer
$actionStack = $this->getContext()->getActionStack();
$actionStack->getFirstEntry()->getActionInstance()->setLayout('yourLayout');
}
$filterChain->execute();
}
}
To avoid unnecessary duplication in the layout file you can work with Fragments and Partials.
I wonder what would be the professional way to handle insert/delete requests of a website?
Right now, what I have is I inserted two <input type = "hidden"/> on each form where one hidden's value correspond to a function it needs and the other is the parameter of this function. So when the form submits, I have a post.php file that handles ALL insert/delete requests that simply invokes the value of the hiddens via call_user_func() in PHP. Like so:
<input name = "arg" value = "{$id}" type = "hidden"/>
<input name = "call" value = "delete_member" type = "hidden"/>
call_user_func($_POST['call'], $_POST['arg']);
I'm having doubts on how sensible this solution is because I found out that the hiddens aren't actually hidden in the source on the client-side.
My first solution was to basically have a lot of conditionals checking for which function to invoke but I really hated that a lot so I changed it with this solution.
I wonder what are the better ways I can do this, or maybe how the professionals do it? Handling insert/delete queries.
I would consider this a very bad way to call actions from the client side.
For one this data is put into the HTML which will always be viewable and editable by the client. As such this means you cannot trust the data you receive from the client and as such you cannot trust the function they are calling.
Another point to re-inforce my previous idea. You say you run validation to make sure it is a function and all that, but you have a problem. Closures return true on these functions (since they are functions and methods and they exist). So a user can put a anon function as the value of your hiden field and actually run whatever they want on your server.
As others say I would recommend looking into MVC. Look into how Yii/CodeIgniter/Zend/Lithium/Kohana/etc do this and how they route.
An example of how routing for actions such as deletion is done by my favourite framework, Yii:
class UserController extends CController{
public function actionDelete($id = null){
if($id===null){ return false; }
}
}
Then the form/link calls /user/delete?id=2 which makes index.php route to the userController and use the actionDelete function inside the user controller, running it's code. Of course this is a very simplified version and it gets a lot more complex to stop vulnerabilities.
You may also wish to look into CSRF validation.
The most common way is to just call a function that takes care of one form at the time like this example for submitting a blog message:
blog.php
if(isset($_POST['submit'])) {
save_message();
} else {
display_form();
}
function display_form()
{
?>
<form action="blog.php"> etc etc....
<?php
}
function save_message()
{
//security checks and inserts etc
$_SESSION['message'] = 'Form saved succesfully';
header('location: blog_overview.php');
}
This is according to me a practish, but you might want to checkout frameworks like Codeigniter and Kohana since the above code is functional (and to me outdated). Read some tutorials about OOP (Object Oriented Programming) and MVC (Model View Controller). It might seem alot of work, but if you really want it to do it right it is worth the time and effort.