Indexing Adds/Changes not working using Lucene in Zend Framework - zend-framework

I am pretty new to programming and definitely to Zend/Lucene indexing. From what I can tell, though, my code is correct. I feel like I may be overlooking a step or something trying to upload changes and adds to the database so that they appear in the search on my website. I'm not getting any kind of an error message though. Below is the code from the controller. I guess let me know if you need anything else to help this make sense. Thanks in advance for any direction you can give.
class SearchController extends Zend_Controller_Action
{
public function init()
{
$auth = Zend_Auth::getInstance();
if($auth->hasIdentity()) {
$this->view->identity = $auth->getIdentity();
}
}
public function indexAction()
{
// action body
}
public function buildAction()
{
// create the index
$index = Zend_Search_Lucene::open(APPLICATION_PATH . '/indexes');
$page = $this->_request->getParam('page');
// build product pages
if ($page == 'search') {
$mdl = new Model_Search();
$search = $mdl->fetchAll();
if ($search->count() > 0) {
foreach ($search as $s) {
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::unIndexed('id', $s->id));
$doc->addField(Zend_Search_Lucene_Field::text('name', $s->name));
$doc->addField(Zend_Search_Lucene_Field::text('uri', $s->uri));
$doc->addField(Zend_Search_Lucene_Field::text('description', $s->description));
$index->addDocument($doc);
}
}
$index->optimize();
$this->view->indexSize = $index->numDocs();
}
}
public function resultsAction()
{
if($this->_request->isPost()) {
$keywords = $this->_request->getParam('query');
$query = Zend_Search_Lucene_Search_QueryParser::parse($keywords);
$index = Zend_Search_Lucene::open(APPLICATION_PATH . '/indexes');
$hits = $index->find($query);
$this->view->results = $hits;
$this->view->keywords = $keywords;
} else {
$this->view->results = null;
}
}
}

Lucene indexes won't stay in sync with your database automatically, you either need to rebuild the entire index or remove and re-add the relevant documents when they change (you cannot edit an existing document).
public function updateAction()
{
// something made the db change
$hits = $index->find("name: " . $name);
foreach($hits as $hit) {
$index->delete($hit->id)
}
$doc = new Zend_Search_Lucene_Document();
// build your doc
$index->add($doc);
}
Note that lucene documents had their own internal id property, and be careful not to mistake it for an id keyword that you provide.

Related

sf 1.4 Access & customize embededObject() in root form

I got a problem to save custom values for embededforms in root form.
I can actually edit a "manifestation" and i can add as much as i want "commande_wifi".
Everything is good saved.
I need to customize the process for every "commande_wifi" ( there is a 'puht' value depending on other values of the object() ). I have already lost a few hours only to do that.
save() is only called on the root form
That’s right! Only the root form has save() called. So if there’s other logic you want to run, you will want to override the saveEmbeddedForm method and call that code before. Oversimplification ahead: when you save a form with embedded forms, it calls $this->getObject()->save(), then it calls saveEmbeddedForms, which, for each embedded form, calls $form->saveEmbeddedForms() and then calls $form->getObject()->save(). This is critical to know, as it will save you a lot of headaches later on.
http://jmather.com/2011/01/29/6-things-to-know-about-embedded-forms-in-symfony/
I've tried to overwrite the saveembededForms() but fail at this point.
class manifestationForm extends BasemanifestationForm
{
public function configure()
{
$this->embedRelation('commande_wifi');
}
public function addNewFields($number){
$new_commandes = new BaseForm();
for($i=0; $i <= $number; $i+=1){
$commande = new Commande_wifi();
$commande->setManifestation($this->getObject());
$commande_form = new commande_wifiForm($commande);
$new_commandes->embedForm($i,$commande_form);
}
$this->embedForm('new', $new_commandes);
}
public function bind(array $taintedValues = null, array $taintedFiles = null){
$new_commandes = new BaseForm();
foreach($taintedValues['new'] as $key => $new_commande){
$commande = new Commande_wifi();
$commande->setManifestation($this->getObject());
$commande_form = new commande_wifiForm($commande);
$new_commandes->embedForm($key,$commande_form);
}
$this->embedForm('new',$new_commandes);
parent::bind($taintedValues, $taintedFiles);
}
public function saveEmbeddedForm($con = null, $forms = null)
{
if ($con === NULL)
{
$con = $this->getConnection();
}
if ($forms === NULL)
{
$forms = $this->getEmbeddedForms();
}
foreach ($forms as $form)
{
if ($form instanceof sfFormObject)
{
$form->saveEmbeddedForms($con);
$form->getObject()->setPuht(99);
$form->getObject()->save($con);
}
else
{
$this->saveEmbeddedForms($con, $form->getEmbeddedForms());
}
//$form->getObject()->setPuht(99)->save();
}
}
}
It's won ASAP i can access the embedForm Object().
Any suggestion?

Is it possible to declare a form object inside a block of if condition in zend framework?

I am very new to zend framework. I want to declare a form object inside an if condition. but I don't know is it possible or not ?. I write the below code:
public function editAction()
{
$modelUsers = new Model_Users();
$userId = $this->_getParam('userId');
if ($userId) {
$populateData = array();
$user = $modelUsers->fetch($userId);
// print_r($user); exit();
if ($user instanceof Model_User) {
$populateData = $user->toArray();
$form = $this->_geteditForm($user->email);
}
$form->populate($populateData);
}
$request = $this->getRequest();
if ($request->isPost()) {
Please let me know I am going to the write path or not.
Thanks in advance
It's OK, but (assuming that it's some kind of a crud) it's better to redirect back to list or throw exception if the ID is missing. Than you don't need to close the whole form in condition. i.e:
if (!$userId = $this->_getParam('userId')) {
throw new Exception('Missing userId');
//or
$this->_helper->redirector('index');
}

Is this a valid way to check if db_row exists?

I am working with Zend and I needed to check whether a row in the DB already exists (A simple solution to get rid of the duplicate key error I was getting). I tried several things but nothing seemed to work... (for example the Zend_Validate_Db_NoRecordExists method)
So I wrote the following the code and I was wondering if this is a valid way to do it, or if I should do things differently:
In the model:
$where = $condition = array(
'user_id = ' . $user_id,
'page_id = ' . $page_id
);
$check = $this->fetchRow($where);
if(count($check) > 0) {
return null;
}else{
// Here I create a new row, fill it with data, save and return it.
}
And then in my view:
if($this->result != null) { /* do stuff */ }else{ /* do other stuff */ }
It does work but it does seem to take more time (duh, because of the extra query) and I am a bit unsure whether I should stick with this..
Any recommendation is welcome :)
Assuming you have coded your function in your controller
$row = $this->fetchRow($where); //If no row is found then $row is null .
if(!$row)
{
$row = $dbTb->createNew($insert); //$insert an associative array where it keys map cols of table
$row->save();
$this->view->row_not_found = true;
}
return $row;
In your view you can do this
if($this->row_not_found)
{
}else {
}

Symfony: exclude empty values from form save

I have a many to many relation between Product and Properties. I'm using embedRelation() in my Product form to edit a Product and it's Properties. Properties includes images which causes my issue. Every time I save the form the updated_at column is updated for file properties even when no file is uploaded.
Therefore, I want to exclude empty properties when saving my form.
I'm using Symfony 1.4 and Doctrine 1.2.
I'm thinking something like this in my ProductForm.class.php, but I need some input on how to make this work.
Thanks
class ProductForm extends BaseProductForm
{
public function configure()
{
unset($this['created_at'], $this['updated_at'], $this['id'], $this['slug']);
$this->embedRelation('ProductProperties');
}
public function saveEmbeddedForms($con = null, $forms = null)
{
if (null === $forms)
{
$properties = $this->getValue('ProductProperties');
$forms = $this->embeddedForms;
foreach($properties as $p)
{
// If property value is empty, unset from $forms['ProductProperties']
}
}
}
}
I ended up avoiding Symfony's forms and saving models instead of saving forms. It can be easier when playing with embedded forms. http://arialdomartini.wordpress.com/2011/04/01/how-to-kill-symfony%E2%80%99s-forms-and-live-well/
Solved it by checking if posted value is a file, and if both filename and value_delete is null I unset from the array. It might not be best practice, but it works for now.
Solution based on http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms
class ProductPropertyValidatorSchema extends sfValidatorSchema
{
protected function configure($options = array(), $messages = array())
{
// N0thing to configure
}
protected function doClean($values)
{
$errorSchema = new sfValidatorErrorSchema($this);
foreach($values as $key => $value)
{
$errorSchemaLocal = new sfValidatorErrorSchema($this);
if(array_key_exists('value_delete', $values))
{
if(!$value && !$values['value_delete'])
{
unset($values[$key]);
}
}
// Some error for this embedded-form
if (count($errorSchemaLocal))
{
$errorSchema->addError($errorSchemaLocal, (string) $key);
}
}
// Throws the error for the main form
if (count($errorSchema))
{
throw new sfValidatorErrorSchema($this, $errorSchema);
}
return $values;
}
}

Zend_Paginator stopped working

I'm learning Zend Framework. I had Zend_Paginator working with the array adapter, but I'm having trouble using the Zend_Paginator::factory static method. The problem is the pagination control links send me to the correct URL, but the results disappear when I click next or page 2, 3, etc.
I have two tables from a database: a file table and an origination_office table. The file table has the client's names, address, etc. and the origination office stores office names (like Tampa, Sarasota, etc.). Each file is associated with an origination office.
My controller:
public function searchAction()
{
$searchForm = new Application_Form_SearchForm();
if ($this->_request->getQuery()) {
if ($searchForm->isValid($this->_request->getParams())) {
$officeName = $this->_request->getParam('officeName');
$page = $this->_request->getParam('page');
}
$fileTable = new Application_Model_DbTable_File();
$this->view->paginator = $fileTable->getFilesByOfficeName($officeName, $page);
}
$this->view->searchForm = $searchForm;
}
Here is the getFilesByOfficeName() method:
public function getFilesByOfficeName($officeName = null, $page = 1, $count = 12, $range = 15, $scrolling = 'Sliding')
{
if (is_null($officeName)) {
$query = $this->select();
$paginator = Zend_Paginator::factory($query);
} else {
$oofTable = new Application_Model_DbTable_OriginationOffice();
$query = $oofTable->select();
$query->where('oof_name like ?', $officeName.'%');
if ($oofTable->fetchRow($query)) {
$origination_office = $oofTable->fetchRow($query);
$files = $origination_office->findDependentRowset($this);
$paginator = Zend_Paginator::factory($files);
} else {
return;
}
}
Zend_Paginator::setDefaultScrollingStyle($scrolling);
Zend_View_Helper_PaginationControl::setDefaultViewPartial('_pagination_control.phtml');
$paginator->setDefaultItemCountPerPage($count);
$paginator->setDefaultPageRange($range);
$paginator->setCurrentPageNumber($page);
return $paginator;
}
Ok, I think I am understanding your problem. Your links are not maintaining the state of your initial request and it's URL query string.
You might want to edit your partial view (_pagination_control.phtml) to render the current query string in your links.
I would need to see what your doing in the partial to give an exact answer, but this should work if you add ?$_SERVER['QUERY_STRING'] to the end of your final URL. See Below Example:
<!-- Your href may look different but notice I append the query string to the end -->
Last »