I want to do the SearchBox on my webapp. I followed tutorial: SeachBox Tutorial excatly, did everything author mentioned, and I'm getting an error:
Index doesn't exists in the specified directory.
My SearchController:
<?php
class SearchController extends Controller
{
private $_indexFiles = 'runtime.search';
public function init(){
Yii::import('application.vendors.*');
require_once('Zend/Search/Lucene.php');
parent::init();
}
/**
* Search index creation
*/
public function actionCreate()
{
$index = Zend_Search_Lucene::create($_indexFiles);
$index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles), true);
$posts = News::model()->findAll();
foreach($news as $news){
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Text('title',
CHtml::encode($news->name), 'utf-8')
);
$doc->addField(Zend_Search_Lucene_Field::Text('link',
CHtml::encode($news->url)
, 'utf-8')
);
$doc->addField(Zend_Search_Lucene_Field::Text('content',
CHtml::encode($news->description)
, 'utf-8')
);
$index->addDocument($doc);
}
$index->commit();
echo 'Lucene index created';
}
public function actionSearch()
{
$this->layout='column2';
if (($term = Yii::app()->getRequest()->getParam('q', null)) !== null) {
$index = new Zend_Search_Lucene(Yii::getPathOfAlias('application.' . $this->_indexFiles));
$results = $index->find($term);
$query = Zend_Search_Lucene_Search_QueryParser::parse($term);
$this->render('search', compact('results', 'term', 'query'));
}
}
}
Any ideas to solve this problem? Thanks for any help.
EDIT: OK, the solution was quite obvious. Index wasn't writed because it wasn't really declared...
this private $_indexFiles = 'runtime.search'; before init should just be in actionCreate function - then it works
Thanks for your help!
You have a typo:
$posts = News::model()->findAll();
foreach($news as $news){
Should be:
$posts = News::model()->findAll();
foreach($posts as $news){
Related
I have a function that loads data from a JSON file and enters it into the TYPO3 database. If I call this function via the backend Controller (indexAction), then everything works fine. However, when I call it from a task, the data is not saved. By means of test output I see that the object was changed correctly, only the Update or Add is not executed correctly, because the data in the database is not changed.
Here is my controller function:
class ImportController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
protected $siteRepository = null;
public function injectSiteRepository(SiteRepository $siteRepository)
{
$this->siteRepository = $siteRepository;
}
public function indexAction()
{
$this->dataImport();
}
public function dataImport() {
$file = "test.json";
$json = file_get_contents($file);
$jsonarray = json_decode($json);
foreach ($jsonarray->{'sites'} as $site) {
$newValue = false;
$dbSite = $this->siteRepository->getSiteByID($site->{'ID'});
if (empty($dbSite->getFirst())) {
$dbSite = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('test\test123\Domain\Model\Site');
$dbSite->setID($site->{'ID'});
$newValue = true;
} else {
$dbSite = $dbSite->getFirst();
}
//Set Data
$dbSite->setTest($site->{'TEST'});
//This object is correct, even in the Task
DebuggerUtility::var_dump(
$dbSite
);
//Update or Add new Data
if (!$newValue) {
$this->siteRepository->update($dbSite);
} else {
$this->siteRepository->add($dbSite);
}
}
$persistenceManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
$persistenceManager->persistAll();
return true;
}
}
Here is my task:
class JsonImportTask extends AbstractTask {
public function execute() {
$objectManager = GeneralUtility::makeInstance(
ObjectManager::class
);
$controller = $objectManager->get(ImportController::class);
$controller->dataImport();
return true;
}
}
Here my repository:
public function getSiteByID($id) {
$query = $this->createQuery();
$query->matching(
$query->equals("uid", $id),
);
return $query->execute();
}
Does anyone have an idea what this could be?
Ok I found my mistake myself. Here is the solution for all who have the same problem:
I added setRespectStoragePage in my getSiteByID function in SiteRepository:
$query->getQuerySettings()->setRespectStoragePage(false);
The error was that it was looking for the data at StoragePid 1. With this command he searches at the right place
Here is my correct repository function:
public function getSiteByID($id) {
$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(false);
$query->matching(
$query->equals("uid", $id),
);
return $query->execute();
}
I had another problem. You have to set the PID number for new entries.
For example, my data is stored on Page ID 12.
I added this line here:
if (empty($dbSite->getFirst())) {
$dbSite = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('test\test123\Domain\Model\Site');
$dbSite->setID($site->{'ID'});
$newValue = true;
$dbSite->setPid(12); //New Line set PID (For me to PID 12)
} else {
$dbSite = $dbSite->getFirst();
}
I want to auto save the sql query every time, I found this article, if I do everything by the page it will work, but the problem is, I have master and slave database, therefore I have to connect to database like:
model/Users.php
<?php
class Users extends CI_Model
{
protected $table = 'users';
public $master;
public $slave;
public function __construct()
{
$this->master = $this->load->database('master', true);
$this->slave = $this->load->database('slave', true);
}
public function save($datas)
{
$this->master->insert($this->table, $datas);
return $this->master;
}
}
Then I adjust demo code like:
<?php
class Query_log
{
public function log_query()
{
$ci =& get_instance();
$filepath = APPPATH . 'logs/Query-log-' . date('Y-m-d') . '.php';
$handle = fopen($filepath, "a+");
$times = $ci->master->query_times;
foreach ($ci->master->queries as $key => $query) {
$sql = $query . " \n Execution Time:" . $times[$key];
fwrite($handle, $sql . "\n\n");
}
fclose($handle);
}
}
Of course I got error message
A PHP Error was encountered
Severity: Notice
Message: Undefined property: Users::$master
Filename: hooks/query_log.php
How to make it right?
I have used Zend_Paginator in my Index action , this show all my catalog :
public function indexAction()
{
Zend_View_Helper_PaginationControl::setDefaultViewPartial('/pagination.phtml');
$pages = new Application_Model_DbTable_Catalog();
$num = 10;
$page = $this->_getParam('page');
$select = $pages->select();
$result = $this->view->table = $pages->fetchAll($select)->toArray();
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($result));
$paginator->setItemCountPerPage($num);
$paginator->setCurrentPageNumber($page);
$paginator->setView($this->view);
$this->view->paginator = $paginator;
}
It works perfectly, now I have CategoryAction, it's sort my catalog by category
public function categoryAction()
{
$id = intval($this->_getParam('id', 0));
if ($id > 0) {
$catalog = new Application_Model_DbTable_Catalog();
$this->view->catalog = $catalog->getByCategoryId($id);
и
$category = new Application_Model_DbTable_Categories();
$this->view->category = $category->getById($id);
}
So I can't understand how to add Pagination to this action,
Help me, Pleaaasssseeeeeee:-(,
P.S. sorry for my bad English
Ok there is a better/easier way to do this.
Pagination starts with your database query. You are using DbTable models so it's very easy in ZF1 to setup the adapter.
<?php
class Application_Model_DbTable_Catalog extends Zend_Db_Table_Abstract
{
protected $_name = 'catalog'
/*
* This method returns a paginator adapter with a fetchAll($where = null, $order = null, $count = null, $offset = null)
* paginator adapter will supply the values for $offset and $limit
*/
public function getPagedCatalog()
{
$select = $this->select(); //put anything you need into $select
$adapter = new Zend_Paginator_Adapter_DbTableSelect($select);//the paginator adapter in place of the fetchAll().
return $adapter;
{
}
<?php
class Application_Model_DbTable_Categories extends Zend_Db_Table_Abstract
{
protected $_name = 'categories'
/*
* This method returns a paginator adapter with a fetchAll($where = $id, $order = null, $count = null, $offset = null)
* paginator adapter will supply the values for $offset and $limit
*/
public function getPagedCatagories($id)
{
$select = $this->select(); //put anything you need into $select
$select->where('catagory_id = ?', $id);//you may need to build a join for this to work how you want it to, depends on your table structure.
$adapter = new Zend_Paginator_Adapter_DbTableSelect($select);//the paginator adapter in place of the fetchAll().
return $adapter;
{
}
now your models will return paginator adapters with the contents of these tables available. Zend_Paginator will automatically supply the $limit and $offset parameters to the query so that each page will perform a query. The whole table will not be stored in memory with this adapter.
Now your indexAction() may look like:
public function indexAction()
{
Zend_View_Helper_PaginationControl::setDefaultViewPartial('/pagination.phtml');
$pages = new Application_Model_DbTable_Catalog();
$adapter = $pages->getPagedCatalog(); //get adapter from model
$page = $this->_getParam('page', 1);//a default of page 1 prevents possible unusual behavior when no page number is set.
$paginator = new Zend_Paginator($adapter);
$paginator->setItemCountPerPage('10');
$paginator->setCurrentPageNumber($page);
//$paginator->setView($this->view); This line is likely not needed
$this->view->paginator = $paginator;
}
and your categoryAction() might work like:
public function categoryAction()
{
$page = $this->_getParam('page', 1);
$id = intval($this->_getParam('id', 0));
if ($id > 0) {
$category = new Application_Model_DbTable_Categories();
$adapter = $category->getPagedCatagories($id);
//same as above
$paginator = new Zend_Paginator($adapter);
$paginator->setItemCountPerPage('10');
$paginator->setCurrentPageNumber($page);
//$paginator->setView($this->view); This line is likely not needed, unless you have multiple view objects.
$this->view->paginator = $paginator;
} else {
//do some other stuff...
}
}
if you get crazy and want to use your own mapper classes to base a paginator adapter on you can extend the adapter class by overriding getItems(), something like:
<?php
class Music_Model_Paginator_Track extends Zend_Paginator_Adapter_DbTableSelect
{
//override getItems()
public function getItems($offset, $itemCountPerPage)
{
$rows = parent::getItems($offset, $itemCountPerPage);
$albums = array();
foreach ($rows as $row) {
$album = new Music_Model_Mapper_Track();//use this class to turn each $row into an object
$albums[] = $album->createEntity($row); //build the new entity objects
}
//returns an array of entity objects to the paginator
return $albums;
}
}
Hope this helps.
I have models in project that use more than one table to select.
How can I write code like this more correct?
public function __construct()
{
$this->_name = DB_PREFIX . 'teachers';
parent::__construct();
}
public function init()
{
$this->db = Zend_Db_Table::getDefaultAdapter();
}
public function getTeachers($course_id)
{
$students_query = $this ->db->select()
->from($this->_name, '')
->from(<ANOTHER_TABLE_NAME>, array('uid', 'ulogin'))
->where("<ANOTHER_TABLE_NAME>.uid = {$this->_name}.teacher_id")
->where("{$this->_name}.course_id = ?", $course_id)
->order("<ANOTHER_TABLE_NAME>.ulogin");
$result = $this->db->fetchAll($students_query) ? $this->db->fetchAll($students_query) : NULL;
return $result;
}
$students_query = $this->db->select()
->from($this->_name, '')
->setIntegrityCheck(false)
->join('<ANOTHER_TABLE_NAME>', "<ANOTHER_TABLE_NAME>.uid = {$this->_name}.teacher_id", array('uid', 'ulogin'))
->where("{$this->_name}.course_id = ?", $course_id)
->order("<ANOTHER_TABLE_NAME>.ulogin");
How Zend_Paginator can work according to the exchange of the variable query?
In line 8 performs a single fetch and does not change even by changing the query variable.
How to do paging function in accordance with the start-index from gdata feed?
The code: http://pastebin.com/rmxSP1Us
$yt = new Zend_Gdata_YouTube();
$limit = 12;
$offset = ($page - 1) * $limit + 1;
$query = "http://gdata.youtube.com/feeds/api/users/aculinario/favorites?start-index=$offset";
$paginator = Zend_Paginator::factory($yt->getVideoFeed($query));
$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage($limit);
$paginator->setPageRange(6);
$this->view->paginator = $paginator;
echo $query // query changes but paginator no, every time Zend_Paginator factory should check the returned array of getVideoFeed, but not this checking
Sry, my poor english, i'm Trying
I got something similar working using a quick & dirty paginator adapter.
It's worth noting there's probably nicer, more generic ways to achieve this. But this will get you going if you're in a hurry.
<?php
class Lib_Paginator_Adapter_YoutubeUser implements Zend_Paginator_Adapter_Interface
{
protected $_username;
protected $_results;
public function __construct($username)
{
$this->_username = $username;
}
public function getItems($offset, $itemCountPerPage)
{
$url = sprintf(
'%s/%s/%s',
Zend_Gdata_YouTube::USER_URI,
$this->_username,
Zend_Gdata_YouTube::UPLOADS_URI_SUFFIX
);
try
{
$query = new Zend_Gdata_Query($url);
$query->setMaxResults($itemCountPerPage)
->setStartIndex($offset);
$youtube = new Zend_Gdata_YouTube();
$this->_results = $youtube->getUserUploads(null, $query);
return $this->_results;
}
catch (Exception $ex)
{
echo $ex->getMessage();
exit;
}
}
public function count()
{
try
{
$youtube = new Zend_Gdata_YouTube();
return $youtube->getUserUploads($this->_username)->getTotalResults()->getText();
}
catch (Exception $ex)
{
echo $ex->getMessage();
exit;
}
}
}
Then in your controller
$page = $this->getRequest()->getParam("page");
$limit = 10;
$username = 'aculinario';
$paginator = new Zend_Paginator(new Lib_Paginator_Adapter_YoutubeUser($username));
$paginator->setItemCountPerPage($limit);
$paginator->setPageRange(10);
$paginator->setCurrentPageNumber($page);
$this->view->youtubeFeed = $paginator;