This is my controller where I am creating json data and passing it to twig file:
/**
*this route is for inserting data into datatable of modal of bootstrap
* #Route("/pagerduty/edit_team_datatable")
* #return Response
*/
public function edit_teble(Request $request){
$edit = new team_details();
$row_id = $request->query->get('row_id');
$query= ("SELECT tr.id, GROUP_CONCAT(u.usrName SEPARATOR ',') AS team_members FROM team_details td
INNER JOIN team_registration tr ON tr.id=td.team_name
INNER JOIN user u ON u.usrid=td.team_members_names
WHERE td.team_name=$row_id
GROUP BY td.team_name");
$em = $this->getDoctrine()->getManager();
$statement = $em->getConnection()->prepare($query);
$statement->execute();
$result = $statement->fetch();
// print_r($result);die;
//return $this->render("team_display.html.twig",array('edit_table'=>$result));
return new JsonResponse($result);
}
I am receiving json response in this manner where id is only "1" and team_members is "8". So now, I want to create 8 id for 8 team members.
This is json data:
{"id":"21","team_members":"teja,preetham,kick,preetham,teja,meuser,kick,preetham"}
What I need is this format using looping:
{"id":"21,21,21,21,21,21,21,21","team_members":"teja,preetham,kick,preetham,teja,meuser,kick,preetham"}
As #Marc_Andre mentioned in the comment above, you should manipulate your data in the controller instead of in the template.
Based on the format of your query result, you can do the following in the controller:
$formatted = [];
$id = $result['id'];
foreach ($result['team_members'] as $member) {
$formatted[] = [$id => $member];
}
return new JsonResponse($formatted);
Related
I'm trying to figure out how I can get the query result like $residence into the data array. because whem im doing this is gives me the error Array to string conversion. Is there any possible way to convert the query result to a normal string?
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function insert(Request $request)
{
$id = auth()->user()->id;
$title = $request->input('title');
$clientid = $request->input('client');
$startdate = $request->input('startdate');
$enddate = $request->input('enddate');
$starttime = $request->input('starttime');
$endtime = $request->input('endtime');
$description = $request->input('description');
$firstname = DB::select('select firstname from clients where id='.$clientid);
$lastname = DB::select('select lastname from clients where id='.$clientid);
$housing = DB::select('select housing from clients where id='.$clientid);
$housenr = DB::select('select housenr from clients where id='.$clientid);
$residence = DB::select('select residence from clients where id='.$clientid);
$residencestring = json_encode($residence);
$data=array(
"uuid"=>$id,
"title"=>$title,
"residence"=>$residencestring,
"startdate"=>$startdate,
"enddate"=>$enddate,
"starttime"=>$starttime,
"endtime"=>$endtime,
"description"=>$description,
"firstname"=>$firstname,
"lastname"=>$lastname,
"housing"=>$housing,
"housenr"=>$housenr
);
//dd($data);
DB::table('tasks')->insert($data);
return redirect('/todo');
}
Notice how you are doing one query for each field? Also, you are getting an array on each query, since the DB::select returns an array with one row, not the row directly as you think.
I would use Query Builder for this for a more elegant solution:
$client = DB::table('clients')->where('id', $clientid)->first();
With this, you have an object named $client that has all the fields from that row.
Then, you can just update the row as follows:
$data = [
'lastname' => $client->lastname,
'firstname' => $client->firstname
];
You could even make it more "Laravel" by using Models.
App/Models/Client.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Client extends Model {
protected $guarded = ['id'];
}
Then your code would look something like this:
<?php
use App\Models\Client;
public function insert(Request $request)
{
....
$client = Client::findOrFail($clientid);
$data = [
'lastname' => $client->lastname,
'firstname' => $client->firstname
];
....
}
The findOrFail function gives you the first register it finds on the table based, equivalent to a "where id=$clientid"
You could go even further and insert using Eloquent as well, as so:
$task = new Task;
$task->lastname = $client->lastname;
$task->firstname = $client->firstname;
$task->save();
or:
$task = Task::insert($data);
where Task is a Model as described previously.
So big thanks to #JoeGalind1! The solution was pretty simple, I had to use the build-in query builder. Instead of using an oldschool query.
This is the solution that worked for me!
$client = DB::table('clients')->select('*')->where('id', $clientid)->first();
once you made this query you can easily call it like this:
$data=array(
"residence"=>$client->residence,
);
Now there are no problems with string conversion and arrays when you need to insert afterwards.
view
<?php
$url = Yii::$app->urlManager->createUrl(['admin/sale/prduct']);
?>
script code in view page
send id whit GET
script in view page
<script>
function ddlcategor(id){
$.ajax({
type:'GET',
url:'<?=$url?>',
data:{id:id},
success: function(data){
$("#test").html(data);
}
});
}
</script>
controller document !
controller
<?php
public function actionProduct($id){
$products = Yii::db->createCommand('select products.* from products right join (select * from product_category where product_category.cat_pro_id ='.$id.') as t on(products.id = t.product_id)')->queryAll();
$option ='';
echo "<option>select ...</option>";
foreach($products as $value){
$option.="<option value=$value->id>$value->title</option>";
}
return $option;
}
?>
Error
PHP Notice - yii\base\ErrorException typing to get property of
non-object
Yii::$app->db->createCommand() returns array. Each row is an associative array with column names and values.
if the selection returns nothing, an empty array will be received.
Yii::$app->db->createCommand()->queryAll();
In your example $value not objact. It is array:
$products = Yii::db->createCommand('select products.* from products right join (select * from product_category where product_category.cat_pro_id ='.$id.') as t on(products.id = t.product_id)')->queryAll();
$option ='';
//No needed in this variant
//echo "<option>select ...</option>";
If(!empty($products)){
foreach($products as $value){
$option.="<option value=$value['id']>$value['title']</option>";
}
}else{
$option.= "<option selected disabled>No results!</option>"
}
return $option;
To debug ajax result I recommend using https://www.getpostman.com/
Using this service, you can track results and errors returned by url pasted to ajax simply.
Try this:
public function actionProduct($id){
$commands = Yii::$app->getDb();
$products = $commands->createCommand('select products.* from products right join (select * from product_category where product_category.cat_pro_id ='.$id.') as t on(products.id = t.product_id)')->queryAll();
$option ='';
echo "<option>select ...</option>";
foreach($products as $value){
$option.="<option value=$value['id']>$value['title']</option>";
}
return $option;
}
I'm trying to make a module for Drupal 7.x. At a certain point I want to use a sql query (JOIN). When I try the query in MYSQL it works. But when I want to try it in Drupal, the array is empty.
So I guess there is a difference between the sql query and the drupal query (mayby the implemantion is different).
SQL Query
SELECT * FROM friends
INNER JOIN users
ON friends.uid=users.uid
Drupal implementation
function project_myfriends(){
// Use database API to retrieve tasks
$query = db_select('friends', 'f');
$query->join('users', 'u', 'f.uid = u.uid'); // JOIN
$query->fields('u', array('name'))
->execute();
return $query;
}
/**
* Implements hook_block_view().
*/
function project_block_view($delta = ''){
switch ($delta) {
case 'project':
$block['subject'] = t('My Friends');
// Use our custom function to retrieve data
$result = project_myfriends();
$items = array();
var_dump($result);
foreach($result as $friend){
$items[] = array(
'data' => $friend->name,
);
}
// No tasks
if (empty($items)) {
$block['content'] = t('No friends.');
}
else {
// Pass data trough theme function
$block['content'] = theme('item_list', array(
'items' => $items));
}
}
return $block;
}
Thx in advance
You forgot to fetch your result query:
$result = project_myfriends()->execute()->fetchAll();
var_dump($result);
I'm trying to return the users like this, but of course it doesn't work, I need the data as JSon since im working with BackboneJs
/**
* #Route("/mytest",name="ajax_user_path")
*/
public function ajaxAction()
{
$em = $this->get('doctrine')->getManager();
$users = $this->get('doctrine')->getRepository('GabrielUserBundle:Fosuser')->findAll();
$response = array("users"=>$users);
return new Response(json_encode($response));
}
Thanks for your help guys, here is the Solution
Get the JMSSerializerBundle,
This is the code on the controller
/**
* #Route("/user")
* #Template()
*/
public function userAction()
{
$em = $this->get('doctrine')->getManager();
$users = $this->get('doctrine')->getRepository('GabrielUserBundle:Fosuser')->findAll();
$serializer = $this->get('jms_serializer');
$response = $serializer->serialize($users,'json');
return new Response($response);
}
So, findAll returns an array of entities (objects) and json_encode cannot correctly encode that array. You have to prepare your data berofe send response like that:
Example:
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* #Route("/mytest",name="ajax_user_path")
*/
public function ajaxAction()
{
$users = $this->get('doctrine')->getRepository('GabrielUserBundle:Fosuser')->findAll();
$response = array();
foreach ($users as $user) {
$response[] = array(
'user_id' => $user->getId(),
// other fields
);
}
return new JsonResponse(json_encode($response));
}
Moreover, it would be great if you put preparing response to ex. UserRepository class.
With Symfony you have JsonResponse like :
return new JsonResponse($users);
And don't forget to add the header :
use Symfony\Component\HttpFoundation\JsonResponse;
I have never tried to encode a complete object, but I have used json with arrays of informations like this:
$vars = array(
'test' => 'test'
);
$response = new JsonResponse($vars);
return $response;
As you can see in JsonResponse, its function setData() is encoding the array, so you don't have to do it yourself:
public function setData($data = array())
{
// Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be embedded into HTML.
$this->data = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
return $this->update();
}
I'm trying to do a query with Zend Framework 2 where I have a SELECT inside a JOIN statement. So far, here's what I've tried, but injecting the SELECT object into the first parameter of join() doesn't seem to be working. I've resorted to such an approach since I need to order the results first before doing any grouping. Any ideas on how to get it working?
public function getSearchKeyword($keyword, $limit)
{
$select = $this->keywords->getSql()->select();
$subquery = $this->pages->getSql()->select();
$subWhere = new \Zend\Db\Sql\Where();
$subWhere->equalTo('delete_flag', 'n')
->equalTo('published_flag', 'y');
$subquery->where($subWhere);
$where = new \Zend\Db\Sql\Where();
$where->like('keyword', '%' . $keyword . '%')
->equalTo('delete_flag', 'n');
$select->columns(array('display' => 'keyword', 'url'))
->join(array('sub' => $subquery), 'sub.page_id = keywords.page_id', array())
->where($where)
->group(array('keywords.page_id', 'keywords.keyword'))
->order(array('rank', 'keyword'))
->limit($limit);
$row = $this->tableGateway->selectWith($select);
return $row;
}
The query I'm trying to write is below:
SELECT keywords.keyword AS display, keywords.url
FROM keywords
INNER JOIN
(
SELECT * FROM pages WHERE published_flag = 'y' AND delete_flag = 'n' ORDER BY page_id DESC
) pages
ON pages.page_id = keywords.page_id
WHERE published_flag = 'y'
AND delete_flag = 'n'
AND keywords.keyword LIKE '%?%'
GROUP BY display, page_id;
I was working around the same problem and did not found a standard way to solve it. So I got a working but not zf2 standard one
Create a small interface to mannage Db conections
Implements it as a small class to get a connection PDO object to
your database
execute your arbitrary querys
Code sample
// Filename: /module/MyTools/src/MyTools/Service/DbModelServiceInterface.php
namespace MyTools\Service;
interface DbModelServiceInterface
{
/**
* Will return the result of querying the curret database
*
* #param type $query
* #result mixed
*/
public function dbQuery($query);
/**
* Will return a connection object that links to curret database
*
* #result mixed
*/
public function getConnection();
}
The class implementing the interface. It creates and offers a PDO connection. Note: It needs extra code to close conns and to perfeorm security adm...
It test it and is completely functional.
code:
// Filename: /module/MyTools/src/MyTools/Service/DbModelServiceMySql.php
namespace MyTools\Service;
use MyTools\Service\DbModelServiceInterface;
use PDO;
class DbModelServiceMySql implements DbModelServiceInterface
{
protected $driverConfig;
protected $connection;
protected $isconnected = FALSE;
protected $dbname = '';
/**
* Creates a connection to main database
*/
public function __construct()
{
$driverConfig = self::getDriverDef();
$this->driverConfig = $driverConfig; // new PDO($driverConfig['dsn'], $driverConfig['username'], $driverConfig['password']);
$this->_connect();
}
protected function _connect(){
$dsn = (isset($this->driverConfig['dsn'])) ? $this->driverConfig['dsn'] : '';
$username = (isset($this->driverConfig['username'])) ? $this->driverConfig['username'] : '';
$password = (isset($this->driverConfig['password'])) ? $this->driverConfig['password'] : '';
if( ($dsn) && ($username) && ($password)){
$options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', ];
try {
$this->connection = new PDO($dsn, $username, $password, $options);
$this->isconnected = TRUE;
$this->_setdbname($dsn);
} catch (Exception $ex) {
throw new RuntimeException('YOUR ERROR MESSAGE.');
}
}
return $this->isconnected;
}
protected function _setdbname($dsn){
if($dsn){
$chunks = explode(';', ''.$dsn);
foreach($chunks as $chunk){
if(strpos('***'.$chunk, 'dbname') > 2){
$nombre = explode('=', $chunk);
$this->dbname = $nombre[1];
break;
}
}
}
}
/**
* {#inheritDoc}
*/
public function dbQuery($query) {
if($this->connection){
$resultset = $this->connection->query($query);
if($resultset){
return $resultset->fetchAll(PDO::FETCH_ASSOC);
}else{
return ['Error' => 'YOUR CUSTOM ERROR MESSAGE.'];
}
}else{
return ['Error' => 'OTHER CUSTOM ERROR MESSAGE'];
}
}
public static function getDriverDef()
{
$autoloadDir = __DIR__ . '../../../../../../config/autoload/';
$credentialsdb = include $autoloadDir . 'local.php';
$globaldb = include $autoloadDir . 'global.php';
$def = (isset($globaldb['db'])) ? $globaldb['db'] : array();
$credentials = (isset($credentialsdb['db'])) ? $credentialsdb['db'] : $credentialsdb;
return array_merge($def, $credentials);
}
/**
* {#inheritDoc}
*/
public function getConnection() {
if($this->connection){
return $this->connection;
}else{
return 'Error: YOUR CUSTOM ERROR MESSAGE';
}
}
/**
* {#inheritDoc}
*/
public function getDbName(){
return $this->dbname;
}
}
Now you have a class you can instantiate elsewhere to perform the querys you need.
use:
code:
$myQuery = 'the very very complex query you need to execute'
$myDbConn = new MyTools\Service\DbModelServiceMySql();
$result = $myDbConn->dbQuery($myQuery);
If success you got a resulset array of pairs columnName => value
You can try this one.
$select->columns(array('display' => 'keyword', 'url'))
->join(array('sub' => 'pages'), 'sub.page_id = keywords.page_id',
array(), $select::JOIN_INNER)
->where($where)
->group(array('keywords.page_id', 'keywords.keyword'))
->order(array('rank', 'keyword'))
->limit($limit);
In your code, you are getting all keywords which page_id's is in sub page_id where delete_flag = 'n' and published_flag = 'y'.
join(..., 'sub.page_id = keywords.page_id', array())
When you don't need any columns of pages table, you can use IN instead of JOIN.
For example when you need to know which keywords are in which pages, you should use JOIN, but when you need to know which keyboards are in any pages, you can use IN statement.
Anyway :
There is no standard way in ZF2 but you can try following code.
public function getSearchKeyword($keyword, $limit)
{
$select = $this->keywords->getSql()->select();
$subquery = $this->pages->getSql()->select();
$subWhere = new \Zend\Db\Sql\Where();
$subWhere->equalTo('delete_flag', 'n')
->equalTo('published_flag', 'y');
$subquery->columns(array('page_id'))
->where($subWhere);
$where = new \Zend\Db\Sql\Where();
$where->like('keyword', '%' . $keyword . '%')
->equalTo('delete_flag', 'n')
->in('keywords.page_id', $subquery);
$select->columns(array('display' => 'keyword', 'url'))
->where($where)
->group(array('keywords.page_id', 'keywords.keyword'))
->order(array('rank', 'keyword'))
->limit($limit);
$row = $this->tableGateway->selectWith($select);
return $row;
}
I've faced a similar issue. Since the FROM table and Subquery's FROM table were different i got an error.
My workaround was to extract the SQL and create a statement.
$sql = $select->getSqlString(new \Zend\Db\Adapter\Platform\Mysql());
$stmt = $this->getAdapter()->createStatement($sql);
$stmt->prepare($sql);
$result = $stmt->execute();
$resultSet = new ResultSet(); \\ Class Zend\Db\ResultSet\ResultSet
$resultSet->initialize($result);