I have a two classes PHP:
Profile
Publicprofile
At Publicprofile class there are:
public function index($id){
$profile = new profile($id, true);
$profile->index();
}
So, here I create a new object profile.
Let's some to see class Profile:
class Profile extends Auth {
public $data = array();
public function __construct($idUser = null, $view = false){
parent::__construct();
$this->getTemplate();
}
}
}
The function getTemplate(); - forms an array $this->data
If to show at once this array after execute getTemplate(), will see (via var_dump), that array contains data with a keys:
view_inside
view
When is called a method $profile->index() - this array not is same:
Method index in class Profile:
public function index(){
var_dump($this->data); die(); // Here there are not keys view_inside, view
$this->route();
}
What is wrong at my code, that the source array in one class is different at two methods?
Function GetTemplate():
public function getTemplate(){
$this->data['view_inside'] = 'profile/doctor/index';
$this->data['view_left'] = 'profile/doctor/left';
$this->data['view_edit'] = 'profile/doctor/personal_update';
$this->data['view_personal'] = 'users/doctor/personal';
var_dump($this->data); // All right
}
Related
i have two helper classes
link are :
C:\xampp\htdocs\ecom\application\views\helpers\comman.php
C:\xampp\htdocs\ecom\application\views\helpers\RefineUrl.php
class Zend_View_Helper_Refinestr
{
public function Refinestr($str, $options = array()){
..............
.............
return $str;
}
}
second is
class Zend_View_Helper_Comman
{
public function Comman(){
return $this;
}
public function getPageContent($pageId){
// return $pageId;
$mapper = new Application_Model_StaticpageMapper();
$selectedFields=array('desc');
$tblName=array($mapper->getDbTable()->_name);
$whr= "`id`=$pageId";
$content=$mapper->fetchSelectedFields($tblName,$selectedFields,$whr);
$des=$content[0]['desc'];
// here i want to use function Refinestr() of another helper class how i use this
$des=$this->Refinestr($des);
// not working , searching this function inside comman class
} }
How to use one helper class function in another helper class function?
You can use below trick for your case.
While calling getPageContent() helper from your view file pass the view object in helper as a param (like $pageId) and use that view object to call another helper in helper definition.
View file:
<?php echo $this->getPageContent($pageId, $this); ?>
Helper File:
class Zend_View_Helper_GetPageContent {
public function getPageContent($pageId, $viewObj) {
// return $pageId;
$mapper = new Application_Model_StaticpageMapper ();
$selectedFields = array ('desc'
);
$tblName = array ($mapper->getDbTable ()->_name
);
$whr = "`id`=$pageId";
$content = $mapper->fetchSelectedFields ( $tblName, $selectedFields, $whr );
$des = $content [0] ['desc'];
// here i want to use function Refinestr() of another helper class how i
// use this
$des = $viewObj->Refinestr($des); //use view object to call another helper
}
}
Another helper will remain as it is.
One more solution to this problem could be, set view object in Zend Registry at the time of bootstrapping and use that registry variable in helper file to call another helper.
In Bootstrap File:
protected function _initConfig() {
$this->bootstrap('view');
$this->_view = $this->getResource('view');
Zend_Registry::set('viewObj', $this->_view);
}
Helper File:
class Zend_View_Helper_GetPageContent {
public function getPageContent($pageId) {
// return $pageId;
$mapper = new Application_Model_StaticpageMapper ();
$selectedFields = array ('desc');
$tblName = array ($mapper->getDbTable ()->_name);
$whr = "`id`=$pageId";
$content = $mapper->fetchSelectedFields ( $tblName, $selectedFields, $whr );
$des = $content [0] ['desc'];
// here i want to use function Refinestr() of another helper class how i
// use this
$viewObj = Zend_Registry::get('viewObj');
$des = $viewObj->Refinestr($des); //use view object to call another helper
}
}
I usually do the following:
Inside helper1
$this->helper1()->view->helper2();
In case helper1 is taking some arguments, I modify it to take no arguments and just return. Try it out, may work.
How exactly does CI custome object works ?
As per CI documentation You can also pass a string to result() which represents a class to instantiate for each result object (note: this class must be loaded)
$query = $this->db->query("SELECT * FROM users;");
foreach ($query->result('User') as $row)
{
echo $row->name; // call attributes
echo $row->reverse_name(); // or methods defined on the 'User' class
}
}
This is a very nice feature yet what Ci does is it will return an array of User objects and set attributes from row to it.
i have a problem with it that i want to have more control on what attributes to be publicly accessed and what to be modified before setting/getting.
how can i accomplish this ? can i tell CI to pass all attributes to constructor so that class can populate its own data ?
example class User
class User{
private $data=array();
protected $CI;
//public $id,$name,$dob,$gender,$role,$username,$password,$salt,$picture,$lastactive;
function __construct($data=null)
{
$this->data = $data; // i want to save data to a private var and allow attr. throu getters only
}
function set_password($p){
$this->generateSalt();
$this->data->password = $p.$this->data->salt;
}
}
In a nutshell::
I want to use custom_result_object but i dont want codeigniter to populate class attributes for me, instead i want the class to receive those attrs and populate it him self the way he this its appropriate.
I found your question while looking for a solution for myself.
After digging a bit in the documentation I managed to figure it out:
class user_item {
// you can declare all the attributes you want as private
private $id,$name,$dob,$gender,$role,$username,$password,$salt,$picture,$lastactive;
function __construct(){
// you can use the constructor to format data as needed
$this->username = strtouppper($this->username);
}
public function set_password($p){
$this->generateSalt();
$this->password = $p.$this->salt;
}
public function get_password(){
return $this->password;
}
}
Once set up, you can instantiate this class from $this->db->result()
class User_model extends CI_Model {
public function get_user($id){
return $this->db->get_where('users', array('id' => $id), 1)->result('user_item');
}
}
And call any public method or attribute of the class as needed
class Users extends CI_Controller {
function __construct(){
$this->load->model('user');
}
public function profile($user_id){
var $myUser = $this->user->get_user($user_id);
$myUser->set_password('myPassword');
echo $myUser->get_password();
}
}
I have simplified the code to make it clearer, but you get the idea.
this example controller using result array and object
if ($this->session->userdata('id_jurusan') ==1) {
$where=array('id_jurusan'=>$this->session->userdata('id_jurusan'));
$value = $this->session->userdata('id_jurusan');
$value2 = $this->session->userdata('username');
$data['rule']=$this->guru_mod->get_where($where,'forward_changing')->result();
$data['fuzzy']=$this->guru_mod->get_data_all('fuzzy')->result();
$data['artikel']=$this->guru_mod->get_data_all('artikel')->result();
$data['kondisi']=$this->guru_mod->get_where($where,'kondisi')->result();
$data['artikel2'] = $this->guru_mod->get_data_all2('artikel','id_jurusan',$value);
$data['riwayat_rule'] = $this->guru_mod->get_data_all2('forward_changing','username',$value2);
$data['kondisi_rule'] = $this->guru_mod->get_data_all2('kondisi','id_jurusan',$value);
$this->load->view('guru/daftar_rule',$data);
}
Trying to get the property inside a function so not sure how to do it.
Here is my class:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Data extends CI_Controller {
public $data;
public function __construct() {
parent::__construct();
$this->load->model('months');
$this->load->driver('cache');
}
}
public function graph1() {
$this->data = $this->months->get_months();
$this->layout->view('graph1', $this->data);
}
So trying to get value of $data inside graph1() in another class, for example:
$object = new Data();
print_r($object->data);
This gives me a blank output, how can i make the $data value have the database result set?
Before dumping your object data, call your graph method to actually get the data. i.e.
$object = new Data();
$object->graph1();
print_r($object->data);
You could also call graph1 from your constructor like:
public function __construct() {
parent::__construct();
$this->load->model('months');
$this->load->driver('cache');
$this->graph1();
}
That way you would be able to actually use:
$object = new Data();
print_r($object->data);
If this solves your problem, I suggest you should read up OOP concepts. Regards.
I will show the real solution that works with the web application and unit testing.
Change this on data controller to:
public function graph1() {
$this->data = $this->months->get_months();
$this->layout->view('graph1', $this->data);
}
To:
public function graph1() {
$this->data = $this->months->get_months();
$this->layout->view('graph1', $this->data);
return $this->data;
}
The return won't cause problems with the layout and views. And will return the correct data to the unit test:
public function testgraph1() {
$object = new Data();
$out = $object->graph1();
print_r($out);
$this->assertArrayHasKey('11', $out);
}
So the other answer is incorrect, and will cause issues with the layout when graph1() is called in the constructor. I don't need to read about OOP but would suggest the person who answered incorrectly to read about web applications and unit testing.
I'm using CakePHP and have created a class as follows:
class ApiController extends AppController {
// functions
}
I have about 10 functions in the class and I have found that I have repeated myself with the exact 3 same lines of code at the beginning of every function:
if ($this->request->is('post')) {
$data = $this->request->input('json_decode',true);
$authUser = explode('.',$_SERVER['PHP_AUTH_USER']);
$location_id = $authUser[1];
// Rest of my function
}
Is there any way that I can create something in the class which runs those 3 lines of code first, and then makes the $data and $location_id variables available for my functions to use, or must I write those 3 lines for every function?
It can be done using private method.
private $data = null;
private $locationId = null;
public function __construct($request = null, $response = null) {
parent::__construct($request = null, $response = null);
$this->data = $this->request->input('json_decode',true);
$authUser = explode('.',$_SERVER['PHP_AUTH_USER']);
$this->locationId = $authUser[1];
}
and then use it like this
$this->locationId;
You can write a method and put the 2 variables as a property of the class.
e.g.
class ApiController {
private $location_id;
private $data;
private function init() {
// ...
}
}
And then access the variables by doing $this->location_id.
I'm trying to decide whether to create many classes for each content type I have in my application/database or just stick with procedural code.
Version 1:
make a class for each object collection:
class App{
protected $user_collection;
function getUserCollection(){
if(!isset($this->user_collection)
$this->user_collection = new UserCollection($this);
return $this->user_collection;
}
// ...
}
class UserCollection{
function __construct(App $app){
$this->app = $app;
}
function getUser($user){
return new User($this->app, $user);
}
function getUsers($options){
$users = $this->app->getDatabase()->query($options);
foreach($users as &$user)
$user = new User($this, $user);
return $users;
}
// ...
}
which I'm using like:
$app = new App();
echo $app->getUserCollection()->getUser('admin')->email_address;
version 2:
keep all methods in a single class
class App{
function getUsers($options){
$users = $this->getDatabase()->query($options);
foreach($users as &$user)
$user = new User($this, $user);
return $users;
}
function getUser($user){
return new User($this, $user);
}
// ...
}
used like:
$app = new App();
echo $app->getUser('admin')->email_address;
version 3:
make getUsers() a a static method in the "User" class (the method instantiates a new User object):
$app = new App();
echo User::getUser($app, 'admin')->email_address;
Which way should I go? The "user" object is just an example, App has other objects too, like "database", "pages" etc.
I would use your version 1, but I would make getUser() and getUsers() methods of App.
This gets rid of the awkward getUserCollection() call, because instead inside the getUser() and what not you just call $this->user_collection.
Personnaly, I often used the second one with method like this:
class user {
/**
* Load object from ...
*/
public function load($userId) {}
/**
* Insert or Update the current object
*/
public function save() {}
/**
* Delete the current object
*/
public function delete() {
// delete object
// Reset ID for a future save
$this->UserID = null;
}
/**
* Get a list of object
*/
public static function getList() {
// Make your search here (from DB)
// Put rows into new "SELF" object
$list = array();
foreach($rows as $row) {
$obj = new self();
$obj->populate($row);
$list[$obj->UserID] = $obj; // Associative array or not...
}
}
}
Like you can see, I set my "getList" function static to simply access like this:
$listUsers = user::getList();
OK, it's very simple but work in most case of simple app.