Array('self' => true), 'OnProcessReciprocalLinks' => Array('self' => true), 'OnSetGrouping' => Array('self' => 'view'), 'OnStoreSelected' => Array('self' => 'view'), 'OnMerge' => Array('self' => 'edit'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Enter description here... * * @param kEvent $event */ function SetCustomQuery(&$event) { parent::SetCustomQuery($event); $object =& $event->getObject(); /* @var $object kDBList */ if (!$this->Application->isAdminUser) { $object->addFilter('expire_filter', '(Expire > '.adodb_mktime().' OR Expire IS NULL)'); } if (substr($event->Special, 0, 10) == 'duplicates') { $object->removeFilter('category_filter'); $link_helper =& $this->Application->recallObject('LinkHelper'); /* @var $link_helper LinkHelper */ $grouping = $link_helper->getGrouping( $event->getPrefixSpecial() ); switch ($event->Special) { case 'duplicates': foreach ($grouping as $group_field) { $object->AddGroupByField($object->TableName.'.'.$group_field); } $object->addFilter('has_dupes_filter', 'DupeCount > 1', kDBList::AGGREGATE_FILTER); break; case 'duplicates-sub': $main_object =& $this->Application->recallObject($event->Prefix.'.duplicates'); foreach ($grouping as $field_index => $group_field) { $object->addFilter('dupe_filter_'.$field_index, '%1$s.`'.$group_field.'` = '.$this->Conn->qstr($main_object->GetDBField($group_field)) ); } break; } $object->addFilter('primary_filter', TABLE_PREFIX.'CategoryItems.PrimaryCat = 1'); } } /** * Set groping fields for link duplicate checker * * @param kEvent $event */ function OnSetGrouping(&$event) { $this->Application->LinkVar($event->getPrefixSpecial(true).'_dupe_fields', $event->getPrefixSpecial().'_dupe_fields'); } /** * Merge duplicate links together (only categories) & delete duplicates * * @param kEvent $event */ function OnMerge(&$event) { $link_helper =& $this->Application->recallObject('LinkHelper'); /* @var $link_helper LinkHelper */ $grouping = $link_helper->getGrouping( $event->getPrefixSpecial() ); $ids = $this->StoreSelectedIDs($event); if (!$ids) { return true; } // check, that user has not selected multiple links from same group $primary_links = Array(); $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $sql = 'SELECT * FROM '.$table_name.' WHERE '.$id_field.' IN ('.implode(',', $ids).')'; $links = $this->Conn->Query($sql, $id_field); $groping_error = false; foreach ($links as $link_id => $link_data) { $group_key = ''; foreach ($grouping as $grouping_field) { $group_key .= 'main_table.`'.$grouping_field.'` = '.$this->Conn->qstr($link_data[$grouping_field]).' AND '; } $group_key = substr($group_key, 0, -5); if (isset($primary_links[$group_key])) { $groping_error = true; break; } else { $primary_links[$group_key] = $link_data['ResourceId']; } } if (!$groping_error) { $temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); $categories_sql = 'SELECT main_table.ResourceId, ci.CategoryId, main_table.'.$id_field.' FROM '.$table_name.' main_table LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON main_table.ResourceId = ci.ItemResourceId WHERE %s'; foreach ($primary_links as $group_key => $primary_resource_id) { $categories = Array(); $group_links = Array(); $group_categories = $this->Conn->Query(sprintf($categories_sql, $group_key)); foreach ($group_categories as $category_data) { $group_links[ $category_data['ResourceId'] ] = $category_data[$id_field]; $categories[$category_data['ResourceId'] == $primary_resource_id ? 'remove' : 'add'][] = $category_data['CategoryId']; } unset($group_links[$primary_resource_id]); $categories = array_unique( array_diff($categories['add'], $categories['remove']) ); if ($categories) { // add link to other link categories $values_sql = ''; foreach ($categories as $category_id) { $values_sql .= '('.$category_id.','.$primary_resource_id.',0),'; } $values_sql = substr($values_sql, 0, -1); $insert_sql = 'INSERT INTO '.TABLE_PREFIX.'CategoryItems (CategoryId,ItemResourceId,PrimaryCat) VALUES '.$values_sql; $this->Conn->Query($insert_sql); } // delete all links from group except primary $temp->DeleteItems($event->Prefix, $event->Special, array_values($group_links)); } } else { $event->status = kEvent::erFAIL; $event->redirect = false; $this->Application->SetVar($event->getPrefixSpecial().'_error', 1); } } /** * Stores ids, that were selected in duplicate checker * * @param kEvent $event */ function OnStoreSelected(&$event) { $this->StoreSelectedIDs($event); $event->SetRedirectParam('pass', 'm,' . $event->getPrefixSpecial()); } /** * Allows to enhance link after creation * * @param kEvent $event */ function OnCreate(&$event) { parent::OnCreate($event); if ($event->status == kEvent::erSUCCESS) { $object =& $event->getObject(); /* @var $object kDBItem */ // replace 0 id in post with actual created id (used in enhancement process) $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); kUtil::array_rename_key($items_info, 0, $object->GetID()); $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); // listing was created -> enhance it right away $enhancement_event = new kEvent('ls:OnRequestEnhancement'); $this->Application->HandleEvent($enhancement_event); if (($enhancement_event->status == kEvent::erSUCCESS) && strlen($enhancement_event->redirect)) { $event->SetRedirectParam('next_template', $event->redirect); $event->redirect = $enhancement_event->redirect; } } } /** * Adds free listing option to listing type selection * * @param kEvent $event */ function OnAfterConfigRead(&$event) { parent::OnAfterConfigRead($event); if (defined('IS_INSTALL') && IS_INSTALL) { return ; } $free_listings = $this->Application->ConfigValue('Link_AllowFreeListings'); $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields'); $virtual_fields['ListingTypeId']['options'] = $free_listings ? Array (0 => 'lu_free_listing') : Array (); $language_id = $this->Application->GetVar('m_lang'); $duplicate_options = array_flip($virtual_fields['DuplicateCheckFields']['options']); $duplicate_options['NAME'] = 'l' . $language_id . '_Name'; $virtual_fields['DuplicateCheckFields']['options'] = array_flip($duplicate_options); $default = $virtual_fields['DuplicateCheckFields']['default']; $virtual_fields['DuplicateCheckFields']['default'] = str_replace('|Name|', '|l' . $language_id . '_Name|', $default); $this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields); if (!$this->Application->isAdminUser) { // for now only on Front-End $this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true); } } /** * contact us form submitted on link details page * * @param kEvent $event */ function OnContactFormSubmit(&$event) { $fields = Array ( 'ContactFormFullName', 'ContactFormEmail', 'ContactFormSubject', 'ContactFormBody', 'ContactFormCaptcha' ); // reset errors var $this->Application->SetVar('ContactForm_HasErrors', ''); // 1. validate form fields $required_fields = $this->Application->GetVar('FormRequiredFields'); foreach ($fields as $field_name) { $field_value = trim($this->Application->GetVar($field_name)); if (in_array($field_name, $required_fields)) { // custom captcha validation if ($field_name == 'ContactFormCaptcha') { if (!strlen($field_value) || ($field_value != $this->Application->RecallVar($event->Prefix . '_captcha_code'))) { $this->Application->SetVar('error_'.$field_name, 1); $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); /* @var $captcha_helper kCaptchaHelper */ $this->Application->StoreVar($event->Prefix . '_captcha_code', $captcha_helper->GenerateCaptchaCode()); $event->status = kEvent::erFAIL; $event->redirect = false; } } // email validation elseif (!strlen($field_value) || ($field_name == 'ContactFormEmail' && !preg_match('/'.REGEX_EMAIL_USER.'@'.REGEX_EMAIL_DOMAIN.'/', $field_value))) { $this->Application->SetVar('error_'.$field_name, 1); $event->status = kEvent::erFAIL; $event->redirect = false; } } } if ($event->status != kEvent::erSUCCESS) { // set errors var $this->Application->SetVar('ContactForm_HasErrors', 1); return ; } $object =& $event->getObject(); // get link object /* @var $object kDBItem */ $send_params = Array( 'from_name' => $this->Application->GetVar('ContactFormFullName'), 'from_email' => $this->Application->GetVar('ContactFormEmail'), 'from_subject' => $this->Application->GetVar('ContactFormSubject'), 'message' => $this->Application->GetVar('ContactFormBody'), 'to_linkname' => $object->GetField('Name'), ); $email_event =& $this->Application->EmailEventUser('LINK.CONTACTFORM', $object->GetDBField('CreatedById'), $send_params); if ($email_event->status == kEvent::erSUCCESS) { $event->redirect = $this->Application->GetVar('success_template'); $redirect_params = Array ( 'opener' => 's', 'pass' => 'all', 'thankyou_header' => $this->Application->GetVar('success_label_header'), 'thankyou_text' => $this->Application->GetVar('success_label_body') ); $event->setRedirectParams($redirect_params); $this->Application->EmailEventAdmin('LINK.CONTACTFORM', null, $send_params); } else { $this->Application->SetVar('error_ContactFormEmail', 1); $event->status = kEvent::erFAIL; $event->redirect = false; } } /** * Makes reciprocal check on link, when it is created * * @param kEvent $event */ function OnBeforeItemCreate(&$event) { parent::OnBeforeItemCreate($event); $this->_checkLink($event); } /** * Makes reciprocal check on link, when it is updated * * @param kEvent $event */ function OnBeforeItemUpdate(&$event) { parent::OnBeforeItemUpdate($event); $this->_checkLink($event); } /** * Makes reciprocal check on link & saves results * * @param kEvent $event */ function _checkLink(&$event) { if (!$this->Application->ConfigValue('ReciprocalLinkChecking')) { return ; } $object =& $event->getObject(); /* @var $object kDBItem */ if ($object->GetDBField('Url') != $object->GetOriginalField('Url')) { // check only when url was changed $link_helper =& $this->Application->recallObject('LinkHelper'); /* @var $link_helper LinkHelper */ $link_checked = $link_helper->CheckReciprocalURL($object->GetDBField('Url')); $object->SetDBField('ReciprocalLinkFound', $link_checked ? LINK_IS_RECIPROCAL : LINK_IS_NOT_RECIPROCAL); if (!$link_checked) { $this->Application->EmailEventAdmin('LINK.RECIPROCAL.CHECK.FAILED'); } } } /** * Update links status by their reciprocal status * * @param kEvent $event */ function OnProcessReciprocalLinks(&$event) { if (!$this->Application->ConfigValue('ReciprocalLinkChecking')) { return ; } $object =& $event->getObject( Array('skip_autoload' => true) ); /* @var $object kDBItem */ $link_helper =& $this->Application->recallObject('LinkHelper'); /* @var $link_helper LinkHelper */ // 1. verify all links, that were not verified previously $sql = 'SELECT ' . $id_field . ' FROM ' . $table_name . ' WHERE (ReciprocalLinkFound = 0)'; $not_checked_links = $this->Conn->GetCol($sql); foreach ($not_checked_links as $link_id) { $object->Load($link_id); $link_checked = $link_helper->CheckReciprocalURL($object->GetDBField('Url')); $object->SetDBField('ReciprocalLinkFound', $link_checked ? LINK_IS_RECIPROCAL : LINK_IS_NOT_RECIPROCAL); $object->Update(); if ($link_checked) { $object->ApproveChanges(); } else { $object->DeclineChanges(); $this->Application->EmailEventAdmin('LINK.RECIPROCAL.CHECK.FAILED'); } } // 2. approve all links, that have succeeded in reciprocal check (during adding/changing on front-end) $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $sql = 'SELECT ' . $id_field . ' FROM ' . $table_name . ' WHERE (ReciprocalLinkFound = ' . LINK_IS_RECIPROCAL . ') AND (Status <> ' . STATUS_ACTIVE . ')'; $verified_links = $this->Conn->GetCol($sql); foreach ($verified_links as $link_id) { $object->Load($link_id); $object->ApproveChanges(); } // 3. decline all links, that failed in reciprocal check (during adding/changing on front-end) $sql = 'SELECT ' . $id_field . ' FROM ' . $table_name . ' WHERE (ReciprocalLinkFound = ' . LINK_IS_NOT_RECIPROCAL . ') AND (Status <> ' . STATUS_DISABLED . ')'; $not_verified_links = $this->Conn->GetCol($sql); foreach ($not_verified_links as $link_id) { $object->Load($link_id); $object->DeclineChanges(); } } /** * Allows to load duplicate link by special id * * @param kEvent $event * @return int */ function getPassedID(&$event) { $id = parent::getPassedID($event); if (($event->Special == 'duplicates') && !is_numeric($id)) { $load_keys = unserialize( base64_decode($id) ); // can't return $load_keys as $id, because "kCatDBItem::GetKeyClause" will ignore them foreach ($load_keys as $field => $value) { $load_keys[$field] = $field . ' = ' . $this->Conn->qstr($value); } $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' WHERE (' . implode(') AND (', $load_keys) . ')'; $id = $this->Conn->GetOne($sql); } return $id; } /** * Returns events, that require item-based (not just event-name based) permission check * * @return Array */ function _getMassPermissionEvents() { $events = parent::_getMassPermissionEvents(); $events[] = 'OnMerge'; return $events; } /** * [HOOK] Allows to add cloned subitem to given prefix * * @param kEvent $event */ function OnCloneSubItem(&$event) { parent::OnCloneSubItem($event); if ($event->MasterEvent->Prefix == 'rev') { $clones = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'Clones'); $subitem_prefix = $event->Prefix . '-' . $event->MasterEvent->Prefix; $clones[$subitem_prefix]['ConfigMapping'] = Array ( 'PerPage' => 'Perpage_LinkReviews', 'ShortListPerPage' => 'Perpage_LinkReviews_Short', 'DefaultSorting1Field' => 'Link_ReviewsSort', 'DefaultSorting2Field' => 'Link_ReviewsSort2', 'DefaultSorting1Dir' => 'Link_ReviewsOrder', 'DefaultSorting2Dir' => 'Link_ReviewsOrder2', 'ReviewDelayInterval' => 'link_ReviewDelay_Interval', 'ReviewDelayValue' => 'link_ReviewDelay_Value', ); $this->Application->setUnitOption($event->MasterEvent->Prefix, 'Clones', $clones); } } }