How to get view as an object into an action helper - php

I have a custom Action Helper that is working fine.
It's generating a dynamic login box if user is not logged in, and if he is, it is generating a menu.
But here I have a problem.
I want to generate that menu from a small view that's called user_menu.phtml
How I can get that view into my view helper, and assign it to an object?
Ok, some update, sorry for being stupid, actualy I have Action Helper:
I'm sorry If I was specific enough while writing my initial question.
So I have a Action helper in: library/Hlp/Action/Helper
That helper renders a form, if user is not loged inn.
Here is my Helper method, that does that job:
public function preDispatch()
{
$view = $this->getView();
$identity = Zend_Auth::getInstance()->getIdentity();
$session = new Zend_Session_Namespace('users_session');
$user_id = $session->idd;
if( !empty($identity) ) {
$userModel = new Application_Model_Vartotojai();
$user_email = $userModel->geUserRowBy('id', $user_id);
$user_email = $user_email['email'];
$view->login_meniu = $identity.' -
[id:'.$user_id.']<br />['.$user_email.'] <br/>
Log OUt';
//here I would like to read view file to an object or some other variable
//if posible to an object si I would be able to inject some values
} else {
$form = new Application_Form_LoginForm();
$view->login_meniu = $form;
$view->register_link = '<br />Register';
//here I would like to read view file to an object or some other variable
//if posible to an object si I would be able to inject some values
}
Additionaly to that form I want to add some links, or other HTML content, that would br stored in a view file.

All you have to do is to extend the Zend_View_Helper_Abstract class. Then you have the view object stored in the public property $view.
By using that object you could render your file with
return $this->view->partial('user_menu.phtml');
Update
Since you've updated your question I will update my answer leaving the previous answer because it's still valid for your previous question.
In your case you already have the $view object, to do what you're asking for in the comments simply use the partial helper attached to the view in this way:
$renderedScript = $view->partial('user_menu.phtml',
array('id' => $user_id, 'email' => $user_email['email']));
By giving an array or an object as second argument to the partial call you can use them as model in your script file. Example:
// content of user_menu.phtml
<h1>Login info</h1>
<p>
[id: <?=$this->user_id?>]<br />
[<?=$this->email?>] <br/>
Log Out'
</p>
P.s. I've used the short_tags + the equal sign (=) shorthand for echo in the view script, if you are not using them you should replace with <?php echo $this->email ?>

From the view, you can pass the this to the helper
myHelper($this,$otherVars )
And then from the helper you can call the other helper
myHelper($view, $otherVars){
$view->otherHelper()
}

Related

Change class property value in method A and access updated value in method B

I'm using a custom PHP framework which is largely based on CodeIgniter.
In one of my controller files, I've set a class property called $orderId. After the user has filled in the form and submitted, I'll do a DB insert, get the order no. and override the $orderId class property value with that order no.
Then I'll redirect to the submit page where I want to access that updated $orderId class property value. This final part is not working, the submit class gets a blank value for property $orderId.
Where am I going wrong pls? The basic example below. Maybe I can't do this because of the redirect and should use a session var instead?
Thanks!
[EDIT] Or I could pass the orderId as the 3rd URL param in the redirect. E.G. redirect('orders/submit/'.self::$orderId); in which case I'll turn all the self:: instances into $this-> for class level scope.
class Orders extends Controller {
private static $orderId;
public function __construct() {
// assign db model
}
public function index() {
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$data = [
// form data to pass to db model
];
self::$orderId = 12345; // example order no. return from db model
if(!empty(self::$orderId)) {
redirect('orders/submit');
}
}
}
public function submit() {
$data = [
'orderId' => self::$orderId
];
$this->view('orders/submit', $data);
}
}
The issue itself is a fundamental architecture problem. static only works when you're working with the same instance. But since you're redirecting, the framework is getting reinitialised. Losing the value of your static property. Best way to go about doing this is by storing the order id in a session variable and then read that variable. Sessions last for the as long as the browser window is open

MVC: Model View interaction in PHP

I'm currently learning the ropes of the MVC pattern and came across a problem I can't seem
to fix in a way I want and is in line with the MVC pattern.
I have set up the router, controllers and views up successfully.
The only thing I don't really get is the use of the Model. I know it's supposed to
serve the Data to the view, and here it is I have a problem.
I want to pass a function thru my view method, but it executes before it should be.
is there a way
I will try to be as specific as possible about the situation so sorry for the long post.
The controller class is this:
class Controller{
private $tpl_name = 'default';
public function model($model){
require('../admin/model/'.$model.'.model.php');
return new $model();
}
public function view($page_title,$file_paths,$params,$data = []) {
// takes an array with the file paths
$this->content = $file_paths;
$tpl_name = $this->tpl_name;
require_once('templates/'.$tpl_name.'/header.php');
require_once('templates/'.$tpl_name.'/nav.php');
require_once('templates/'.$tpl_name.'/content-top.php');
foreach ($file_paths as $content){
require_once('view/'.$content);
}
require_once('templates/'.$tpl_name.'/content-bottom.php');
require_once('templates/'.$tpl_name.'/footer.php');
}
}
The view renders the template I want, takes parameters from the router and, the data that
needs to be handled in the desired view. So far so good.
I want to serve my posts in my admin panel that displays a table of all the posts in the DB.
I have written a method that fetches the data, and a method that writes the data.
class Post{
......
//other functions above
public function displayPosts(){
// get's all the posts form the data base, returns an object array
$posts = Post::fetchContent('posts',0);
// array get's passes to the write function which will write out the data.
$writer = Post::write($posts);
}
static public function write(Array $posts){
foreach($posts as $single){
// for each object in the array, assign the vars so the view can handle them
// to create a single row in the table for each object:
$trashed = $single->getTrashed();
$id = $single->getID();
$title = $single->getTitle();
$category = $single->getCategory();
$content = $single->getContent();
$author = $single->getAuthor();
$date = $single->getDate();
$approved = $single->getApproved();
$dbt = $single->getDbt();
// This is a template which represents a table row with the post data I need.
require('view/content_table.php');
}
//controller file (needs to moved to other file later): handles approve/remove/edit/delete actions.
require('view/manage_content.php');
}
}
Now we have arrived at the problem:
When I call the model in my controller and render the view, it will execute immediatly
before the rest of my view loads, resulting in errors, although it displays the data,
it is not in my template, but above it, just in plain text.
errors:
Notice: Undefined variable: _SESSION in /Volumes/HDD Mac/Websites/server/admin/view/content_table.php on line 8
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at ...)
class Dashboard extends Controller {
public function index($params = null){
$model = $this->model('Post');
$posts = $model->displayPosts();
// view takes: page_title,[array of view files],params from the router,array of data from model
$this->view('Dashboard',['admin.php'],$params,[ 'posts' => $posts]);
}
}
Before I was trying to use MVC I just outputted this in my view:
And it worked just fine.
Non relevant HTML above
$posts = Post::fetchContent('posts',0);
// array get's passes to the write function which will write out the data.
$writer = Post::write($posts);
Non relevant HTML below
But now when I pass the display post function, I just want to do this in my view:
echo $data['posts'];
which doesn't work because it already executed my Write function.
The only way I could work around like this was by adding the content of my write function to the view,
and only pass the fetchContent method to my view method (this will output an array of objects).
But since I need this info in two place I dont want to repeat this code, I would prefer echoing
all out.
Non relevant HTML above
$posts = $data['posts'];
foreach($posts as $single){
// for each object in the array, assign the vars so the view can handle them
// to create a single row in the table for each object:
$trashed = $single->getTrashed();
$id = $single->getID();
$title = $single->getTitle();
$category = $single->getCategory();
$content = $single->getContent();
$author = $single->getAuthor();
$date = $single->getDate();
$approved = $single->getApproved();
$dbt = $single->getDbt();
// This is a template which represents a table row with the post data I need.
require('view/content_table.php');
}
//controller file (needs to moved to other file later): handles approve/remove/edit/delete actions.
require('view/manage_content.php');
Non relevant HTML below
Is it bad practise to just skip the use of the Model here and do it like this:
Non relevant HTML above
$posts = Post::fetchContent('posts',0);
// array get's passes to the write function which will write out the data.
$writer = Post::write($posts);
Non relevant HTML below
Or is there a way to rewrite my Post::Write function? Or just use the foreach loop in the view?
Thank you all for taking the time!
If you need more info, just ask:-)

Can't access session variable in Kohana controller

I have mysterious issue with kohana framework.
I create session variable in controller function:
public function action_authorise()
{
session_start();
$_SESSION["user"] = "superAdmin";
}
Later in the same controller's another function I try to access this season:
public function action_getSession()
{
$this->template->test = $_SESSION["user"];
$this->template->content = View::factory('admin/main');
}
The problem is that when I call $test variable in admin/main view it returns empty string, but if I call implicitily $_SESSION["user"] in admin/main view, it returns "superAdmin" as it should.
Can anyone see mistake while calling session variable in controller? Thanks
The problem here is that you're passing the variable test to the view template and it needs to be passed to the view admin/main. You can do this a couple of ways, pick whichever one you like best:
// Create the view object
$partial_view = View::factory('admin/main');
// Assign the session value to the partial view's scope as `test`
$partial_view->test = $_SESSION["user"];
// Assign the partial view to the main template's scope as `content`
$this->template->content = $partial_view;
Shortcut syntax:
$this->template->content = View::factory('admin/main', array(
'test' => $_SESSION['user'],
));
You passing test variable to template view, but trying to access it it admin/main view. There is no test variable in admin/main view. These are different views. Each one has its own variables.
You should set test to admin/main view like:
public function action_getSession()
{
$this->template->content = View::factory('admin/main')
->set('test', $_SESSION["user"]);
}
Also there is very usefull Session class in Kohana. It takes care of session business within framework.
Take a look at user guide.

How do i call the function I created in my Model on the view

I just created this function in the model to see who im following in my social network... how do i call it in the view??
function isfollowing($following){
$user_id = $this->session->userdata('uid');
$this->db->select('*');
$this->db->from('membership');
$this->db->join('following', "membership.id = following.tofollow_id");
$this->db->where("tofollow_id","$following");
$this->db->where("user_id", "$user_id");
$q = $this->db->get();
if($q->num_rows() > 0) {
return "yes";
} else {
return "no";
}
}
Now in my VIEW how do i call it being that i had already made a function to get the current logged on user's id and that is equal to $r->id
How do i call it here?? what goes after the "==" in that if statement?
THE VIEW
<?php if ( $r->id == ): ?>
It is not a good practice to call model function from view.
There are some alternatives about it. You can use anyone you like.
First
When you are loading a view call your model function and pass it in a variable
than this variable will be passed to view.
Controller
$following_status = $this->my_model->isfollowing($following);
$data['following_status'] = $following_status;
$this->load->view('my_view',$data);
View
<p>$following_status</p>
Secound
If you want to be independent of model you can create helper which you can
use anywhere in the application. You will have to create a CI instance to
get it working.
custom_helper.php
function isfollowing($following)
{
$CI = get_instance();
$user_id = $CI->session->userdata('uid');
$CI->db->select('*');
$CI->db->from('membership');
$CI->db->join('following', "membership.id = following.tofollow_id");
$CI->db->where("tofollow_id","$following");
$CI->db->where("user_id", "$user_id");
$q = $CI->db->get();
if($q->num_rows() > 0) {
return "yes";
} else {
return "no";
}
}
View
//load the custom helper before using it (you can autoload of in autoload.php)
//or use common way $this->load->helper('custom');
<p>isfollowing($yourparameter)</p>
You do the following:
(1) Load your model in the controller that creates your page or auto load it
(2) In your view, type something like:
$this->The_custom_model->isfollowing($theinputvariable)
where The_custom_model is the model where you defined the isfollowing() function.
$theinputvariable is the appropriate argument value for your function. Keep in mind that you have specified an object as the argument to your function so you need to think about that.
this is an amended version to what raheel posted showing an if check - probably not necessary for your question, but to give you some things to think about...
// check to see if anything come back from the database?
if ( ! $data['following_status'] = $this->my_model->isfollowing($following) ) {
// nothing came back, jump to another method to deal with it
$this->noFollowers() ; }
// else we have a result, and its already set to data, so ready to go
else {
// do more here, call your view, etc
}
databases can go down even if the web page is working so its good to get in the habit of checking the results. the more error checks you can do in your controller and models, the cleaner your view files will be.
To access model into your view you first load it into autoload file like this
$autoload['model'] = array('model_name');
then in view you can get it by using this line of code
$this->model_name->isfollowing($following)
in isfollowing you will pass your tofollow_id

Get value of custom user field in Drupal 7 template?

I'm building my first site with drupal. And I made a custom user field: Full name.
Now I want to get the value of this fild in my template to say “Hello, %username%”.
How do I do that?
Clive's answer is correct except that you should use field_get_items to get the values for a field. It will handle the language for you. You should also sanitize the value.
function THEME_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$full_names = field_get_items('user', $user, 'field_full_name');
if ($full_names) {
$vars['full_name'] = check_plain($full_names[0]['value']);
}
}
If your site uses the Entity API module, you can also use a entity metadata wrapper like this
function THEME_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$wrapper = entity_metadata_wrapper('user', $user);
$vars['full_name'] = $wrapper->field_full_name->get(0)->value(array('sanitize' => TRUE));
}
See also Writing robust code that uses fields, in Drupal 7
Depending on your setup/field name, something like this in template.php (preprocess function for the template file):
function mytheme_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$vars['full_name'] = $user->field_full_name[LANGUAGE_NONE][0]['value'];
}
Then something like this in page.tpl.php:
if (isset($full_name) && !empty($full_name)) :
echo 'Hello ' . $full_name;
endif;
Note that LANGUAGE_NONE may need to be changed if you're running a multi-lingual site.
I know this question was asked quite a while ago, but I wanted to post an alternative. It looks like you want to change the field in the $variables array that is $variables['name'] to what you have in your custom field that I've called field_real_name. If you are using a preprocess function, there is no need to pull in the global $user object. You have access to the $variables array, so you can get the user information with this - it will load the information associated with the uid (see template_preprocess_username):
function mythemename_preprocess_username(&$variables) {
$account = user_load($variables['account']->uid);
...more code will go here in a moment
}
If you dpm($account) (or kpr($account) if you aren't using devel) you will see that you have access to all of the user information, without using the global $user object.
Then you can change the output of $variables['name'] to be your field_real_name as follows:
function mythemename_preprocess_username(&$variables) {
// Load user information with user fields
$account = user_load($variables['account']->uid);
// See if user has real_name set, if so use that as the name instead
$real_name = $account->field_real_name[LANGUAGE_NONE][0]['safe_value'];
if (isset($real_name)) {
$variables['name'] = $real_name;
}
}
We can add the below code anywhere in the template file.
<?php
global $user;
$user = user_load($user->uid);
print $user->name;
?>

Categories