Zend Framework 2 Query - php

How can customised my query.. this is my current code in my controller:
class PostController extends AbstractActionController
{
private $userTable;
// CRUD
// retrieve
public function indexAction(){
return new ViewModel(
array(
'rowset' => $this->getPostsTable()->select(),
)
);
}
public function getPostsTable(){
if(!$this->userTable){
$this->userTable = new TableGateway(
'posts',
$this->getServiceLocator()->get('Zend\Db\Adapter\Adapter')
);
}
return $this->userTable;
}
}
How can i order the result to descending?
And how to join another table with that code?

First of all, Zend framework is an MVC Framework.
Means that your Data Object Access MUST be in Model layer NOT IN Controller.
Your PostController can't have Model logic in it, it's bad. And it may be throw so much error that you will not understand directly.
Plus, call getServiceLocator in Controller is a bad practise and it will be removes in Zf3. That's why using Model Layer is recommanded.
For your problem, you have to make a query builder like this :
$sql = new \Zend\Db\Sql\Sql($this->getAdapter());
$select = $sql->select()
->from('tableName')
->columns(array())
->join('tableName2', 'Your ON Clause')
->where(array('if you Have WhereClause'))
->order('Your column DESC');
I use Doctrine but i'm pretty sure (community will confirm this or not) this example may work.

Related

How to complete data provided by a CActiveRecord model in Yii?

I'm working on a Yii 1.1.16 application and have following difficulty:
There is a model FooModel based on the CActiveRecord. Behind it is a database table bar_table with a very inconvenient data structure:
id: integer
some_column: string
data: string <- JSON
That means, I get almost the whole data as a JSON string. (Yes, it's crazy, but now I accept it as given.)
In the view the data should get passed to CGridView widget and shown as a table. That means, I have to modify the data, in order to display it.
I see to possibilities / places to do that:
On the model layer, probably in the model class. Then the widget will get the modified data and process it as usual.
On the view layer, probably in the view file. Then I'll have to modifiy the data I got from the model and pass it somehow to the widget.
What is the better approach (or maybe there is a much more elegant one and how to implement it?
Here is a an ugly solution (ugly because a public property is used), anyway it works:
model class Foo
class Foo extends CActiveRecord {
...
public $buz;
...
public function findAll($condition, $params=array()) {
$resultData = parent::findAll($condition='', $params);
foreach ($resultData as $key => $insuranceExternal) {
$data = json_decode($insuranceExternal->getAttribute('data'), true);
$insuranceExternal->setAttribute('myAdditionalProperty', $data['baz']['buz']);
}
return $resultData;
}
}
view
$dataProvider = $model->search();
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'my-grid',
'dataProvider'=>$dataProvider,
'filter'=>$model,
'columns'=>array(
...
'myAdditionalProperty',
),
));
you could use the "afterFind" method/event to handle your json data
class Foo extends CActiveRecord {
protected function afterFind()
{
$this->data = json_decode($this->data);
}

customized function raw query in Laravel framework

Please indicate me where i can add a customized function in Laravel framework or is there something missing in the installation?
i'm trying to use the function
public function select($query, $bindings = array())
{
return $this->run($query, $bindings, function($me, $query, $bindings)
{
if ($me->pretending()) return array();
// For select statements, we'll simply execute the query and return an array
// of the database result set. Each element in the array will be a single
// row from the database table, and will either be an array or objects.
$statement = $me->getPdo()->prepare($query);
$statement->execute($me->prepareBindings($bindings));
return $statement->fetchAll($me->getFetchMode());
});
}
from the tutorial http://fideloper.com/laravel-raw-queries
but i cannot find where to modify my existing Laravel framework.
I need to run a query have inner join from 3 tables and collect the data and post it in grid. I need to modify in Laravel framework and create a function of my own.
Please help.
Thank you.
yes so in your controllers you have method that correspond to a route.
So choose the method corresponding to your route and call this function in that method.
For example in your HomeController.php
Class HomeController extends BaseController {
public function index() {
$yourData = DB::raw('your query');
// if you want to inject it in your view.
return View::make('yourtemplatename', ['yourdata' => $yourData]);
}
}
And in your file routes.php
route::get('/', 'HomeController#index');
But there is prettiest way to do queries with Eloquent.
Check the documentation for that.Your query is not as hard as it looks it a forest of join.

Maintaining an MVC pattern, making database calls from model using PHPs Laravel 4

I'm trying to maintain an MVC pattern using the Laravel 4 framework, in my last project I made all the database queries from the controller, I have now learned that is a terrible practice and I'm trying to figure out how to do the same from the model. Here is what I would normally do.
Controller
public function serve($company)
{
$review = Review::select('head', 'body', 'logo', 'name')->where('company', '=', $company)->firstOrFail();
return View::make('layouts.singlereview', compact('review'));
}
Model
class Review extends Eloquent {
protected $table = 'reviews';
protected $guarded = [
'id', 'company', 'head', 'body'
];
}
When I move the $review variable and database query into the model then I get the error on the view with undefined variable. How do I pass the $review variable from the model to the controller?
Thanks!
Actually you will still need to do some stuff with your Models in your controller. Use Repository Pattern do to so, which is pretty similar of querying your models in your controller, but being less verbose:
public function serve($company)
{
return View::make('layouts.singlereview')->withReview(with(new Review)->getCompanyData($company));
}
And put the whole logic in your repository:
class Review extends Eloquent {
public function getCompanyData($company)
{
return static::select('head', 'body', 'logo', 'name')
->where('company', '=', $company)
->firstOrFail();
}
}
Also, while you are on the subject of creating good code, you might as well check out Eloquent relationships. They may require database restructuring for certain occurrences, but most of the time you should be good.
With the code you have provided, I can assume that review and company are in a one-to-one relationship, so once this is defined, you can simply retrieve a company object, then do,
$review = $company->review;

How to avoid boilerplate code in my models?

I am using CI, however this question applies to models and db persistence in general. I find myself creating methods in models like:-
private function create_joins() {
# Add some joins to the global db object using the active record
}
I do this so I can then perform common joins for a particular model without duplicating the code for creating the joins.
So a select method might be:-
public function get_by_id($id) {
$this->db->select('some_cols');
$this->db->from('some_table');
$this->create_joins();
$this->db->where(array('id' => $id));
etc...
}
Which is fine, but I am wondering if this is the sort of thing that an ORM like datamapper can abstract away?
You should try Doctrine, which is one of the most advanced ORM in PHP:
Using Doctrine, you won't even have to write methods such as get_by_id($id) in your model : they are handled by Doctrine itself.
So you would be able to write:
$entityManager->find("Bug", $id);
An alternative is to use php-activerecord via sparks
An example of Associations
-
class User extends ActiveRecord\Model{
//set tablename
//I would advice to keep Model singular and table names plural
//then this next step is not needed
static $table_name = 'table_one';
//set relationships
static $belongs_to array(
array('Group')
);
static $has_many = array(
array('Comment'),
array('Order')
);
static $has_one = array(
array('Additional_Info')
);
//one key feature is callbacks
//this helps keep controllers clean by letting you pass
//the post data(after validation) in to modify(serialize,json_encode,calculate vat etc)
static $before_create = array('json_encode_my_tags');
public function json_encode_my_tags(){
//$this->tags === $this->input->post('tags');
$tags = explode(',', str_replace(' ', '', $this->tags));
return $this->tags = json_encode($tags, TRUE);
}
}
//calling a model and using eager-loading for associations
$model = User::find(array(
'conditions' => array('id=?', $id) // PK Primary key
'include' => array('comment', 'order', 'additional_info') // eager-loading associations
));
$model->key;
$model->comment->key;
$model->additional_info->key;
$model->order->key;

findByExample in Doctrine

Is there a method in Doctrine like Hibernate's findByExample method?
thanks
You can use the findBy method, which is inherited and is present in all repositories.
Example:
$criteria = array('name' => 'someValue', 'status' => 'enabled');
$result = $em->getRepository('SomeEntity')->findBy($criteria);
You can create findByExample method in one of your repositories using a definition like this:
class MyRepository extends Doctrine\ORM\EntityRepository {
public function findByExample(MyEntity $entity) {
return $this->findBy($entity->toArray());
}
}
In order for this to work, you will have to create your own base class for the entities, implementing the toArray method.
MyEntity can also be an interface, which your specific entities will have to implement the toArray method again.
To make this available in all your repositories, ensure that you are extending your base repository class - in this example, the MyRepository one.
P.S I assume you are talking about Doctrine 2.x
Yes.
Let's say you have a model called Users. You have the following two classes
abstract class Base_User extends Doctrine_Record
{
//define table, columns, etc
}
class User extends Base_User
{
}
in some other object you can do
$user = new User;
//This will return a Doctrine Collection of all users with first name = Travis
$user->getTable()->findByFirstName("Travis");
//The above code is actually an alias for this function call
$user->getTable()->findBy("first_name", "Travis");
//This will return a Doctrine Record for the user with id = 24
$user->getTable()->find(24);
//This will return a Doctrine Collection for all users with name=Raphael and
//type = developer
$user->getTable()
->findByDql("User.name= ? AND User.type = ?", array("Raphael", "developer"));
$users = $userTable->findByIsAdminAndIsModeratorOrIsSuperAdmin(true, true, true);
See http://www.doctrine-project.org/projects/orm/1.2/docs/manual/dql-doctrine-query-language/en

Categories