$this->fetchRow creates failure in phpunit in Zend framework - zend-framework

I followed Rob Allens ZF 1 Tutorial and wanted to pimp it up with some UnitTesting. But whenever I run the phpunit command, i get the message:
here was 1 failure:
1) IndexControllerTest::testDeleteAction
Failed asserting last controller used <"error"> was "Index"
/path/to/library/Zend/Test/PHPUnit/ControllerTestCase.php:1000
/path/to/tests/application/controllers/IndexControllerTest.php:55
FAILURES!
Tests: 4, Assertions: 9, Failures: 1.
The Action in question is the deleteAction and looks like this:
public function deleteAction() {
if ($this->getRequest()->isPost()) {
$del = $this->getRequest()->getPost('del');
if ($del == 'Yes') {
$id = $this->getRequest()->getPost('id');
$wishes = new Application_Model_DbTable_Wishes();
$wishes->deleteWish($id);
}
$this->_helper->redirector('index');
}
else {
$id = $this->_getParam('id', 0);
$wishes = new Application_Model_DbTable_Wishes();
$this->view->wish = $wishes->getWish($id);
}
}
I tracked the error down to be $wishes>getWish($id); so if i go to that function, that looks like this:
public function getWish($id) {
$id = (int) $id;
$row = $this->fetchRow('id = ' . $id);
if(!$row){
throw new Exception("Could not find row $id");
}
return $row->toArray();
}
it appears the line $row = $this->fetchRow('id = ' . $id); causes the problem. And I can't figure out why. All action work just fine, they do as expected.Any idea how to fix this?
Thanks!

Maybe try using the select() object instead if a plain string:
public function getWish($id) {
$id = (int) $id;
$select = $this->select();
$select->where('id = ?', $id);
$row = $this->fetchRow($select);
if(!$row){
throw new Exception("Could not find row $id");
}
return $row->toArray();
}
This just a wild guess, but who knows. The only thing that looks at all odd is the lack of a placeholder in the query string (?).
FetchRow() does like to work with the select() object, in fact if you pass a string the first thing fetchRow() does is build a select(). So maybe it just doesn't like the string.

Related

Symfony createView causes error

I am using Symfony 3.3.10
I have the following code
/**
* #Route("/meta/edit/{metaId}", name="edit_price_meta_data")
*/
public function editMetaAction(Request $request,ItemPriceMeta $metaId)
{
$metaDataForm = $this->createForm("ItemBundle\Form\ItemPriceMetaType");
$data = [
'metaData'=>$metaId,
'metaDataForm'=>$metaDataForm->createView(),
];
return $this->render("#Item/Prices/Manage/editMetaData.html.twig",$data);
}
It produces the following error.
Error: Maximum execution time of 60 seconds exceeded
in vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php (line 2513)
public function createEntity($className, array $data, &$hints = array()){
$class = $this->em->getClassMetadata($className);
//$isReadOnly = isset($hints[Query::HINT_READ_ONLY])
$id = $this->identifierFlattener->flattenIdentifier($class, $data);
$idHash = implode(' ', $id);
if (isset($this->identityMap[$class->rootEntityName][$idHash])) {
$entity = $this->identityMap[$class->rootEntityName][$idHash];
$oid = spl_object_hash($entity);
The actual line highlighted as causing the error is $id = $this->identifierFlattener->flattenIdentifier($class, $data);
Removing 'metaDataForm'=>$metaDataForm->createView(), from my array, removes the error, so it seems to be the rendering of the form that is causing the error.
Increase PHP memory usage in php.ini

syntax for selecting the last recordset in my model

I tried different possibilities but nothing worked, in the tutorial I couldn't find an example either.
I have a method in my modelclass:
public function getlastImport($filename)
{
//$id = (int) $id;
$rowset = $this->tableGateway->select(['Path' => $filename]);
$row = $rowset->current();
if (! $row) {
throw new RuntimeException(sprintf(
'Could not find row with identifier %d',
$id
));
}
return $row;
}
I want to retrieve the last import of a given filename, so ist must be like in sql:
select max(ID) from table where filename = $filename;
But how would be the right syntax in this case?
The sql query should be
"SELECT * FROM table_name WHERE filename={$filename} ORDER BY id DESC LIMIT 1"
Use as the following in your model
public function getlastImport($filename)
{
$select = $this->tableGateway->getSql()->select();
$select->columns(array('id', 'filename', 'label'));
$select->where(array('filename' => $filename));
$select->order("id DESC");
$select->limit(1);
$result = $this->tableGateway->selectWith($select);
$row = $result->current();
if (! $row) {
throw new RuntimeException(sprintf(
'Could not find row with identifier %d',
$id
));
}
return $row;
}
Hope this would help you!

Zend insert user and set value to max()+1

My code:
public function insertMember($member)
{
$maxOrderNumber = $this->select()
->from($this, array(new Zend_Db_Expr('max(order_number)')));
$id = $this->insert($member, $maxOrderNumber);
return $id;
}
I want to insert member to last position in members table and order_number entity. Tried with $maxOrderNumber but i keep getting 0 value in database.
Im using MySql. Also i have user_id with (AI) Autoincrement so i'm forced to function this way.
public function insertMember($member)
{
$maxOrderNumber = $this->select()
->from($this, array(new Zend_Db_Expr('max(order_number)')));
$stmt = $maxOrderNumber ->query();
$result = $stmt->fetchAll();
$id = $this->insert($member, $result ['order_number']);
return $id;
}
soemthing like that...

How to prevent SQL injection in PhalconPHP when using sql in model?

Let's say I am building a search that finds all the teacher and got an input where the user can put in the search term. I tried reading the phalcon documentation but I only see things like binding parameters. I read the other thread about needing prepare statements do I need that in Phalcon as well?
And my function in the model would be something like this:
public function findTeachers($q, $userId, $isUser, $page, $limit, $sort)
{
$sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
$result = new Resultset(null, $this,
$this->getReadConnection()->query($sql, array()));
$tagResult = $result->toArray();
$tagList = array();
foreach ($tagResult as $key => $value) {
$tagList[] = $value['id'];
....
}
}
My question is for the Phalcon framework is there any settings or formats I should code for this line $sql = 'SELECT id FROM tags WHERE name LIKE "%' . $q . '%"';
And also any general recommendation for preventing SQL Injection in PhalconPHP controllers and index would be appreciated.
For reference:
My controller:
public function searchAction()
{
$this->view->disable();
$q = $this->request->get("q");
$sort = $this->request->get("sort");
$searchUserModel = new SearchUsers();
$loginUser = $this->component->user->getSessionUser();
if (!$loginUser) {
$loginUser = new stdClass;
$loginUser->id = '';
}
$page = $this->request->get("page");
$limit = 2;
if (!$page){
$page = 1;
}
$list = $searchUserModel->findTeachers($q, $loginUser->id, ($loginUser->id)?true:false, $page, $limit, $sort);
if ($list){
$list['status'] = true;
}
echo json_encode($list);
}
My Ajax:
function(cb){
$.ajax({
url: '/search/search?q=' + mapObject.q + '&sort=<?php echo $sort;?>' + '&page=' + mapObject.page,
data:{},
success: function(res) {
//console.log(res);
var result = JSON.parse(res);
if (!result.status){
return cb(null, result.list);
}else{
return cb(null, []);
}
},
error: function(xhr, ajaxOptions, thrownError) {
cb(null, []);
}
});
with q being the user's search term.
You should bind the query parameter to avoid an SQL injection. From what I can remember Phalcon can be a bit funny with putting the '%' wildcard in the conditions value so I put them in the bind.
This would be better than just filtering the query.
$tags = Tags::find([
'conditions' => 'name LIKE :name:',
'bind' => [
'name' => "%" . $q . "%"
]
])
Phalcon\Filter is helpful when interacting with the database.
In your controller you can say, remove everything except letters and numbers from $q.
$q = $this->request->get("q");
$q = $this->filter->sanitize($q, 'alphanum');
The shortest way for requests:
$q = $this->request->get('q', 'alphanum');

Zend_Search_Luncene handle Querys

iam trying to implement an Searchmachine into my site. Iam using Zend_Search_Lucene for this.
The index is created like this :
public function create($config, $create = true)
{
$this->_config = $config;
// create a new index
if ($create) {
Zend_Search_Lucene_Analysis_Analyzer::setDefault(
new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive()
);
$this->_index = Zend_Search_Lucene::create(APPLICATION_PATH . $this->_config->index->path);
} else {
$this->_index = Zend_Search_Lucene::open(APPLICATION_PATH . $this->_config->index->path);
}
}
{
public function addToIndex($data)
$i = 0;
foreach ($data as $val) {
$scriptObj = new Sl_Model_Script();
$scriptObj->title = $val['title'];
$scriptObj->description = $val['description'];
$scriptObj->link = $val['link'];
$scriptObj->tutorials = $val['tutorials'];
$scriptObj->screenshot = $val['screenshot'];
$scriptObj->download = $val['download'];
$scriptObj->tags = $val['tags'];
$scriptObj->version = $val['version'];
$this->_dao->add($scriptObj);
$i++;
}
return $i;
}
/**
* Add to Index
*
* #param Sl_Interface_Model $scriptObj
*/
public function add(Sl_Interface_Model $scriptObj)
{
// UTF-8 for INDEX
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::text('title', $scriptObj->title, 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::text('tags', $scriptObj->tags, 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::text('version', $scriptObj->version, 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::text('download', $scriptObj->download, 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::text('link', $scriptObj->link));
$doc->addField(Zend_Search_Lucene_Field::text('description', $scriptObj->description, 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::text('tutorials', $scriptObj->tutorials, 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::text('screenshot', $scriptObj->screenshot));
$this->_index->addDocument($doc);
}
But when i try to query the index with :
$index->find('Wordpress 2.8.1' . '*');
im getting the following error :
"non-wildcard characters are required at the beginning of pattern."
any ideas how to query for a string like mine ? an query for "wordpress" works like excepted.
Lucene cannot handle leading wildcards, only trailing ones. That is, it does not support queries like 'tell me everyone whose name ends with 'att'' which would be something like
first_name: *att
It only supports trailing wildcards. Tell me everyone whose names end that start with 'ma'
first_name: ma*
See this Lucene FAQ entry:
http://wiki.apache.org/lucene-java/LuceneFAQ#head-4d62118417eaef0dcb87f4370583f809848ea695
There IS a workaround for Lucene 2.1 but the developers say it can be "expensive".