Zend framework 2 CSV data as an array or string - zend-framework2

I am still very new to Zend and running into some issues on exporting my data to a CSV.
I found a great resource that explains the headers and download part here however I am running into issues when trying to export the actual data.
If I create a variable like $content = "test" the export works fine using the code above.
However when I duplicate my indexAction code, make some changes, and bring it into my downloadAction, I am getting issues that I believe are due to my content being returned as an Object rather than an array or string.
My Module is grabbing the SQL by using:
public function fetchAllMembers($order = null , $order_by = null, $selectwhere = null) {
$session = new SessionContainer('logggedin_user');
$sql = new Sql($this->adapter);
$select = new Select();
$select->from(array('u' => 'tbl_all_data'));
if ($selectwhere != null){
$select->where($selectwhere);
}
$select->order($order_by . ' ' . $order);
$selectString = $sql->getSqlStringForSqlObject($select);
$results = $this->adapter->query($selectString, Adapter::QUERY_MODE_EXECUTE);
$results->buffer();
return $results;
}
and my Controller is calling that SQL by using:
$content = $modulesTable->fetchAllMembers($order, $order_by, $where);
Any help would be greatly appreciated, and I don't need anyone to write the code for me just help with pointoing me in the right direction.

$this->adapter->query returns a Zend\Db\ResultSet object. So you need to call $results = $results->toArray(); to send an array.
Also you need to loop through the array and echo it out in your view file.

Results, returned by adapter are ResultSet type. I guess you need to call at least
current()
method to grab some data. And they will be of array type, so, again you need to do something with them.
toArray() is often used to quickly get data.
More sophisticated way to get data, is to use next() method with current():
$firstThing = $result->current();
$result->next();
$result->next();
$thirdThing = $result->current();
It's just an example, but it can be useful in some cases.

Related

Executing simple query issue in Zend 2

I want to execute two queries in zend 2 :
This is the content of my model file:
$email = $getData['login_email'];
$password = $getData['login_password'];
$select = $this->adapter->query ("select count(*) as counter from users where email = '$email' and password = '".md5($password)."'");
$results = $select->execute();
if ($results->current()['counter'] == 1 ){
// $update_user = $this->adapter->query("UPDATE users SET session_id = '".$session_id."' WHERE email = '".$email."'");
try {
$update_user = $this->adapter->query("select * from users");
} catch (\Exception $e) {
\Zend\Debug\Debug::dump($e->__toString()); exit;
}
$update_session = $update_user->execute();
For some reason if i remove one random query, the another one will be executed. I know it is weird but i believe there is a rational answer to it. The result of the try catch part is:
I did not write it wrong the query. AS you can see I tried a simple select query and i got the same result. Actually I have no idea what is wrong this. Please help with this, I'm looking up for an answer on the internet during the last 5-6 days and I found nothing. If you want me to provide any more information, please ask. THX
As this answer suggests, this is an issue with the mysqli driver using unbuffered queries by default.
To fix this, you have to buffer the result of the first query before running the next one. With ZF2, the Result interface has a buffer() method to achieve this :
$results = $select->execute();
$results->buffer();

How do I query complex data and return the data in the correct objects in Zend Framework 2?

I'm just starting out with ZF2 and I've run into a stumbling block and I cant find any useful advice on the internet.
Setting up retrieval of data from a single table and injecting it directly into a specific model is easy, for example, pulling data from a single row from 'school' table and injecting to a 'school' model.
However, I have some slightly more complex data and can't figure out how to return the data in the form of the correct model. For example, pulling multiple addresses from a school address table with a join on the school table.
I've got the following method in my AddressTable object...
public function fetchAllSchoolAddresses($school_id)
{
$stmt = $this->adapter->createStatement();
$stmt->prepare("CALL get_school_addresses(3)");
$stmt->getResource()->bindParam(3, $school_id, \PDO::PARAM_INT, 3);
$resultSet = $stmt->execute();
$addresses = new \ArrayObject();
if(!empty($resultSet)){
foreach ($resultSet as $result) {
$addresses->append($result);
}
}
return $addresses;
}
This quite nicely returns an array of addresses data but I want these results to be returned as Address objects. I'm not sure how to do this?
ZF2 comes with some standard Hydrators, which you can extend / modify if you wish.
http://framework.zend.com/manual/2.0/en/modules/zend.stdlib.hydrator.html
You could create a Hydrator for your School Object, and a Hydrator for your Address object.
The hydrators will build the object for you given the array data from the database for example
For example, you would Hydrate your School Object, and then find all addresses (like above) and use another hydrator to hydrate those. You would then add those to the School object to get your object graph as needed
$school->addAddress($address); // etc
Have a look here to see an example of using Hydrators and Hydrating ResultSets:
http://blog.evan.pro/zf2-tablegateway-hydration
http://framework.zend.com/manual/2.0/en/modules/zend.db.result-set.html
for exampple you could do something like this:
// How ever you want to get your database result do it here..
// this is where you get all addresses for your School
$stmt = $driver->createStatement($sql);
$stmt->prepare($parameters);
$result = $stmt->execute();
$resultSet = new HydratingResultSet(new ReflectionHydrator, new SchoolAddress);
$resultSet->initialize($result);
foreach ($resultSet as $address) {
$school->addAddress($address);
echo $address->getCity() . ' ' . $user->getPostcode() . PHP_EOL;
}
You would have a resultset (collection) of Addresses to add to your School.
That's code is just a very rough example hacked from the code in the docs to give an idea of what you do
How about this?
if(!empty($resultSet)){
foreach ($resultSet as $result) {
$address = new Address();
$address->exchangeArray($result);
$addresses->append($address);
}
}

Fetch values of aggregated columns in Propel

I am trying to make following query in Propel:
$criteria = new Criteria();
$criteria->clearSelectColumns();
$criteria->addSelectColumn(TableName::COLUMN1)
->addSelectColumn(TableName::COLUMN2)
->addAsColumn('alias1', 'DATE('.TableName::INIT_TIME.')')
->addAsColumn('alias2', 'COUNT('.TableName::DOWNLOAD_START_TIME.')')
->addGroupByColumn('DATE('.TableName::INIT_TIME.')')
->addGroupByColumn(TableName::DOWNLOAD_START_TIME);
$logs = TableName::doSelect($criteria);
It seems that everything OK and according to MySQL log file query generated and saved to server right. However I cannot get values of aggregated columns.
doSelect returns array of TableName objects which have no methods to fetch aggregated columns. So, how can I do it?
PS: I am talking about symfony 1.4 with Propel if it matters.
You should avoid the use of Criteria, use the ModelCriteria API instead (documentation available at: http://www.propelorm.org/reference/model-criteria.html)
The following query:
<?php
$criteria = new Criteria();
$criteria->clearSelectColumns();
$criteria->addSelectColumn(TableName::COLUMN1)
->addSelectColumn(TableName::COLUMN2)
->addAsColumn('alias1', 'DATE('.TableName::INIT_TIME.')')
->addAsColumn('alias2', 'COUNT('.TableName::DOWNLOAD_START_TIME.')')
->addGroupByColumn('DATE('.TableName::INIT_TIME.')')
->addGroupByColumn(TableName::DOWNLOAD_START_TIME);
$logs = TableName::doSelect($criteria);
Can be rewritten as below:
$query = TableNameQuery::create()
->select(array('Column1', 'Column2'))
->withColumn('DATE(InitTime)', 'alias1')
->withColumn('COUNT(DownloadStartTime)', 'alias2')
->groupBy('alias1')
->groupByDownloadStartTime()
;
$logs = $query->find();
Note you won't select both columns alias1 and alias2 as you didn't add them to the selected columns in your code. You can do that by adding the two alias to the select() clause:
->select(array('Column1', 'Column2', 'alias1', 'alias2'))
I used this snippet to retrieve and fetch data when I followed this same approach, but selecting only one column in my criteria through addSelectColumn:
$logs = TableName::doSelectStmt($criteria);
$data = $logs->fetchAll(PDO::FETCH_COLUMN, 0);
I hope this can help you.
My method is to make a query and iterate through a recordset. As suggested I use FETCH_BOTH to get array positions, but names as well. I take those values and hydrate my object, but also manually populate the properties of the object that are meant to hold the aggregate values. I pass those objects back to my application and use them as normal objects would be used in my view.
$stmt = self::doSelectStmt($c);
// empty array for now
$results = array();
// lets iterate through this
while($row = $stmt->fetch(PDO::FETCH_BOTH)) {
// we need to create a new object
$division = new Division();
// and we'll hydrate each row turning into an object so we can use it easily
$division->hydrate($row);
// now here's the magic, this object did not exist from our tables, we'll fix that
$division->setNumPlayers($row['num_players']);
$division->setNumTeams($row['teams']);
// set the output object
$results[] = $division;
}
return $results; // array of objects including aggregate values

jQuery autocomplete not displaying my encoded values

I am working from this example: http://jqueryui.com/demos/autocomplete/#remote and I am encoding the output like this:
$rows = array();
while($r = mysql_fetch_assoc($category_result))
{
$rows[] = $r;
error_log ("rows: ".$rows[0]);
}
echo json_encode($rows);
But the dropdown on the other side shows nothing. Here is my test page: http://problemio.com/test.php - if you enter "ho" it matches 2 results in the database, but they are not getting displayed for some reason. Any idea why?
Thanks!!
The properties should be named label and value. From the JQuery UI demo page you linked to:
The local data can be a simple Array of Strings, or it contains
Objects for each item in the array, with either a label or value
property or both. The label property is displayed in the suggestion
menu.
So you would need to rename category_name to label either in PHP or later on in your JavaScript source handler function. The latter would require you to replace the PHP URL with a callback function like in the remote example. That way you could get the data any way you want (e.g. by jQuery.getJSON()) and work with it before it gets handed over to the suggestion box.
Hope this helps.
Regarding your comment, this should do it:
$rows = array();
while ($r = mysql_fetch_array($category_result)) {
$rows[] = array("label" => $r["category_name"]);
}
echo json_encode($rows);

Filter BindingSource with entity framework

Hi
How can i filter results exists in BindingSource filled with entities ( using EF 4)?
I tried this:
mybindingsource.Filter = "cityID = 1"
But it seems that binding source with entity framework doesn't support filtering .. am i right ?,is there another way to filter(search) data in binding source .
PS:
- I'm working on windows application not ASP.NET.
- I'm using list box to show the results.
Thanx
Maybe a better one than Leonid:
private BindingSource _bs;
private List<Entity> _list;
_list = context.Entities;
_bs.DataSource = _list;
Now when filtering is required:
_bs.DataSource = _list.Where<Entity>(e => e.cityID == 1).ToList<Entity>;
This way you keep the original list (which is retrieved once from the context) and then use this original list to query against in memory (without going back and forth to the database). This way you can perform all kinds of queries against your original list.
I think, you have made mistake in syntax. You should write Filter like this:
mybindingsource.Filter = "cityID = '1'"
Another way is to use LINQ expressions.
(About LINQ)
Why do you have to call Entety again?
Simple solution:
public List<object> bindingSource;
public IEnumerable FiltredSource
{
get{ return bindingSource.Where(c => c.cityID==1);
}
.where (Function (c) c.cityID = 1)

Resources