Joomla component : one view calling multiple models? - model-view-controller

I want a view to call 2 different models for use.
Controller.php
class StatsController extends JController {
function display()
{
if( !JRequest::getVar( 'view' ) ) {
JRequest::setVar('view', 'stats' );
}
parent::display();
}
...
...
}
Stats view : (index.php?option=com_stats&view=stats)
class StatsViewStats extends JView
{
function display($tpl = null)
{
$model_helpdesk = & JModel::getInstance('Helpdesk','StatsModel');
//$model_chart = & JModel::getInstance('Chart','StatsModel');
//$model_chart = &$this->getModel('Chart');
var_dump($model_chart);
...
...
parent::display($tpl);
}
}
Problem : getting the Helpdesk model works fine, but getting the Chart model either returns a blanc page , or returns null in var_dump. How can i get this second model for use (without modifying the controller) ??

In your controller, you'll need to do the following:
$view = &$this->getView('Stats', 'html');
$view->setModel($this->getModel('Stats'), true);
$view->setModel($this->getModel('Chart'));
$view->setModel($this->getModel('Helpdesk'));
$view->display();
Then you can access each model using the following:
$chartModel = $this->getModel('Chart');
$helpdeskModel = $this->getModel('Helpdesk');
Source

Related

CodeIgniter hide post id and only title show in URL

I am working in Codeigniter and I want to hide ID from URL.
my current URL is:
www.localhost/CI/services/1/ac_repair
but need this type of URL in codeigniter:
www.localhost/CI/services/ac_repair
View Page Code:
<?=anchor('services/' . $ser->s_id . '/' . url_title($ser->s_title,'_') ,'View Service');?>
Controller Code:
public function services()
{
$this->load->model('ServicesModel', 'ser_model');
$s_id = $this->uri->segment(2, 0);
if($s_id){
$get_service = $this->ser_model->get_ser($s_id);
return $this->load->view('public/detail', compact('get_service') );
}
else
{
// $services = $this->articles->articles_list( $config['per_page'], $this->uri->segment(3) );
$get_services['result'] = $this->ser_model->all_services_list();
// $this->load->view('public/services', ['services'=>$services]);
$this->load->view('public/services', $get_services);
}
}
Model Code here:
public function get_ser($id)
{
// $q = $this->db
$q = $this->db->select('*')
->from('services')
->where( ['s_id' => $id] )
->get();
if ( $q->num_rows() )
return $q->row();
return false;
}
but need this type of URL in codeigniter:
www.localhost/CI/services/ac_repair
If you want this functionality you have to be able to use your title ac_repair in place of the id. This means the title needs to be marked as unique and therefore not contain any duplicates.
The following pseudo-code should give you an idea:
function services($url_title = null) {
if (!is_null($url_title)) {
// get ser would use title instead of $id
$this->db->where('title', $url_title);
} else {
// all rows
}
}
Other methods would be "hacky" and I cannot think of any off the top of my head that I would consider usable.
Side note: you should never be returning in a view

Adding custom eloquent attribute in Laravel 5

I have a function named siblings which fetches all siblings of a user.
select siblings(id) as `siblings` from users where id = 1
I can access the function in Eloquent as
User::where('id', 1)->first([DB::raw(siblings(id) as `siblings`)]->siblings;
I want to make the siblings available via custom attribute.
I added siblings to $appends array
I also created getSiblingsAttribute method in my User model as
public function getSiblingsAttribute()
{
if (!$this->exists()) {
return [];
}
$siblings = User::where('idd', $this->id)
->first([DB::raw('siblings(id) AS `siblings`')])
->siblings;
return explode(',', $siblings);
}
But this is not working as $this->id returns null
My table schema is users(id, username,...), so clearly id is present.
Is there a way by which I can bind the siblings function while querying db and then returning something like $this->siblings from getSiblingsAttribute. If I can bind siblings(id) as siblings with query select globally as we do for scopes using global scope.
That way my code can be simply
public function getSiblingsAttribute()
{
return $this->siblings;
}
The simplest way is to create a view in your database and use that as a table:
protected $table = 'user_view';
Otherwise I need more information about your id == null problem.
If you can fix this by your own in the next step it is important that you use an other column name by selecting as in your accessor otherwise you run in an infinite loop.
public function getSiblingsAttribute()
{
if (!$this->exists()) {
return [];
}
$siblings = User::where('id', $this->id)
->first([DB::raw('siblings(id) AS `siblings_value`')])
->siblings_value;
return explode(',', $siblings);
}
EDIT
Sadly there is no simple way to archieve this.
But after a little bit tinkering I have found a (not very nice) solution.
Give it a try.
You have to add the following class and trait to your app.
app/Classes/AdditionalColumnsTrait.php (additional column trait)
namespace App\Classes;
trait AdditionalColumnsTrait {
public function newEloquentBuilder($query) {
$builder = new EloquentBuilder($query);
$builder->additionalColumns = $this->getAdditionalColumns();
return $builder;
}
protected function getAdditionalColumns() {
return [];
}
}
app/Classes/EloquentBuilder.php (extended EloquentBuilder)
namespace App\Classes;
use Illuminate\Database\Eloquent\Builder;
class EloquentBuilder extends Builder {
public $additionalColumns = [];
public function getModels($columns = ['*']) {
$oldColumns = is_null($this->query->columns) ? [] : $this->query->columns;
$withTablePrefix = $this->getModel()->getTable() . '.*';
if (in_array('*', $columns) && !in_array($withTablePrefix, $oldColumns)) {
$this->query->addSelect(array_merge($columns, array_values($this->additionalColumns)));
} elseif (in_array($withTablePrefix, $oldColumns)) {
$this->query->addSelect(array_values($this->additionalColumns));
} else {
foreach ($this->additionalColumns as $name => $additionalColumn) {
if (!is_string($name)) {
$name = $additionalColumn;
}
if (in_array($name, $columns)) {
if (($key = array_search($name, $columns)) !== false) {
unset($columns[$key]);
}
$this->query->addSelect($additionalColumn);
}
}
if (is_null($oldColumns)) {
$this->query->addSelect($columns);
}
}
return parent::getModels($columns);
}
}
after that you can edit your model like this:
class User extends Model {
...
use App\Classes\AdditionalColumnsTrait;
protected function getAdditionalColumns() {
return [
'siblings' => DB::raw(siblings(id) as siblings)),
];
}
...
}
now your siblings column will be selected by default.
Also you have the option to select only specific columns.
If you don't want to select the additional columns you can use: User::find(['users.*']).
Perhaps it is a solution for you.

Symfony 1.4 doctrine model object data retrieve issue

In my symfony 1.4 application i'm using doctrine data models.I'm new to symfony and doctrine.I generated doctrine models from command-line after defining database table information in the schema.yml file.Those generated successfully.Then i created a custom function inside Table.class.php file.Following is that.
class Table extends BaseTable
{
public function getuname()
{
$user=new Table();
$uname=$user->getUsername();
return $uname;
}
}
I want to know how to call this inside the controller ? I called it normal MVC application's way.But i don't know whether it's correct in symfony.In symfony 1.4 manual also i couldn't find a proper way to do this.
This is my controller.
class loginActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$this->userdata = User::getuname();
}
}
Then i tried to print this inside view.
<?php
echo $userdata;
?>
But view is showing an empty page.
Update with exception details--------------------------------
stack trace
at ()
in SF_SYMFONY_LIB_DIR\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Connection.php line 1082 ...
$message .= sprintf('. Failing Query: "%s"', $query);
}
$exc = new $name($message, (int) $e->getCode());
if ( ! isset($e->errorInfo) || ! is_array($e->errorInfo)) {
$e->errorInfo = array(null, null, null, null);
}
When using Doctrine you retrieve objects from the database using the ...Table classes (in your case it will be a TableTable class. You can use its' methods to fetch objects from DB (e.g. find($id)) and then access them. So in your case your classes should something like this:
class Table extends BaseTable
{
public function getuname()
{
return $this->getUsername();
}
}
Now it effectively becomes just an alias of getUsername().
Then in your action:
class loginActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$user = Doctrine_Core::getTable('Table')->find(123);
$this->userdata = $user->getuname();
}
}
This will print the username in your template (assuming of course that you have a user with id 123).

How to disable render view in zend framework 2?

I want to use some ajax, but I don't know how to use function as the same as setNoRender() in zend framework 2 to disable for render view.
How to disable rendering view in zend framework 2?
To disable your view :
public function myactionAction()
{
// your code here ...
return false;
}
"return false" disables the view and not the layout! why? because the accepted types are:
ViewModel
array
null
so "false" disable the view.
To disable layout and view, return a response object:
public function myactionAction()
{
// your code here ...
return $this->response;
}
To disable layout:
public function myactionAction()
{
// your code here ...
$view = new ViewModel();
$view->setTerminal(true);
return $view;
}
If you're using JSON, then look at the view's JsonStrategy and return a JsonModel from you controller. See this article.
Alternatively, you can return an Response from your controller and the whole view layer is skipped:
public function testAction()
{
$response = $this->getResponse();
$response->setStatusCode(200);
$response->setContent('foo');
return $response;
}
Proper and simple solution to do this
public function testAction()
{
$data = array(
'result' => true,
'data' => array()
);
return $this->getResponse()->setContent(Json::encode($data));
}
Details: http://cmyker.blogspot.com/2012/11/zend-framework-2-ajax-return-json.html
I found some answer.
Though $this->layout()->getLayout() returns the name/path of the newly selected layout... The layout does not change with any of the following commands...
within a controller
$this->getLocator()->get('view')->layout()->setLayout('layouts/ajax.phtml');
$this->getLocator()->get('view')->layout()->setLayout('ajax');
$this->getLocator()->get('view')->layout()->disableLayout();
within a view PHTML file
$this->layout()->setLayout('layouts/ajax.phtml');
$this->layout()->setLayout('ajax');
$this->layout()->disableLayout();
$view = new ViewModel();
$view->setTerminate(true);
...
use Zend\View\Model\JsonModel;
public function myAction() {
...
$view = new JsonModel($myArray);
$view->setTerminal(true);
return $view;
}

RedBean ORM and Codeigniter, how to make Fuse recognize models loaded from CI default models path?

Codeigniter has its own Models path, where models extend from CI_Model. I'm using RedBean has a library in Codeigniter, loading it on a controller. After loading Rb, I try to use CI Loader to load a model that extends redbean_simplemodel (wish works, there's no error), but the events / methods inside the model have no effect when they're called on bean.
For example,
APPPATH/application/libraries/rb.php
class Rb {
function __construct()
{
// Include database configuration
include(APPPATH.'/config/database.php');
// Get Redbean
include(APPPATH.'/third_party/rb/rb.php');
// Database data
$host = $db[$active_group]['hostname'];
$user = $db[$active_group]['username'];
$pass = $db[$active_group]['password'];
$db = $db[$active_group]['database'];
// Setup DB connection
R::setup("mysql:host=$host;dbname=$db", $user, $pass);
} //end __contruct()
} //end Rb
And then on
APPPATH/application/models/model_song.php
class Model_song extends RedBean_SimpleModel {
public function store() {
if ( $this->title != 'test' ) {
throw new Exception("Illegal title, not equal «test»!");
}
}
}
while on
APPPATH/application/controllers/welcome.php
class Welcome extends CI_Controller {
public function index()
{
$this->load->library('rb');
$this->load->model('model_song');
$song = R::dispense('song');
$song->title = 'bluuuh';
$song->track = 4;
$id = R::store($song);
echo $id;
}
}
My question is, how to make RedBean (FUSE http://redbeanphp.com/#/Fuse) work on Codeigniter ?
Thanks for looking!
----- FOUND SOLUTION!
Actually, it's working! I was trying to place code under my model, method store(). That wont work! I tryed to place a new method called update() and it does work! Check the example below:
class Model_song extends RedBean_SimpleModel {
public function update() {
if ( $this->title != 'test' ) {
throw new Exception("Illegal title!");
}
}
}
The solution is the following:
"Assuming that you've already installed RedBean on Codeigniter"
1) Load the library for «redbean»
2) Using ci_loader, load the desired model (the model must extend redbean_simplemodel)
Thanks for looking! I hope this helps other people too.
The solution is the following:
"Assuming that you've already installed RedBean on Codeigniter"
Load the library for «redbean»
Using ci_loader, load the desired model (the model must extend redbean_simplemodel)

Resources