Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Mar 11, 3:31 AM

in-portal

Index: branches/RC/kernel/units/files/file_eh.php
===================================================================
--- branches/RC/kernel/units/files/file_eh.php (revision 9597)
+++ branches/RC/kernel/units/files/file_eh.php (revision 9598)
@@ -1,166 +1,55 @@
<?php
class FileEventHandler extends kDBEventHandler {
/**
* [HOOK] Allows to apply file functionality to specific config
* When main item is created, then #file config is cloned
*
* @param kEvent $event
*/
function OnDefineFiles(&$event)
{
$clones = $this->Application->getUnitOption('#file', 'Clones');
$clones[$event->MasterEvent->Prefix.'-file'] = Array (
'ParentPrefix' => $event->MasterEvent->Prefix,
);
$this->Application->setUnitOption('#file', 'Clones', $clones);
}
/**
* Remembers user, who is created file record. Makes file primary if no other files are uploaded.
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
- parent::OnBeforeItemCreate($event);
-
- $object =& $event->getObject();
-
- $this->resetPrimary($object);
-
- if (!$this->primaryFileFound($object)) {
- $object->SetDBField('IsPrimary', 1);
- $object->SetDBField('Status', STATUS_ACTIVE);
- }
-
$object->SetDBField('CreatedById', $this->Application->RecallVar('user_id'));
}
/**
* Resets primary file mark when more then one file is marked as primary
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$object =& $event->getObject();
- $this->resetPrimary($object);
-
if (!$object->GetDBField('FileName')) {
$object->SetDBField('FileName', basename($object->GetDBField('FilePath')));
}
}
- /**
- * Checks for primary file along all files with same main item
- *
- * @param kDBItem $object
- * @return int
- */
- function primaryFileFound(&$object)
- {
- $sql = 'SELECT '.$object->IDField.'
- FROM '.$object->TableName.'
- WHERE (IsPrimary = 1) AND ('.$this->getParentClause($object).')';
- return $this->Conn->GetOne($sql);
- }
-
- /**
- * Resets primary mark from all item files
- *
- * @param kDBItem $object
- */
- function resetPrimary(&$object)
- {
- if (!$object->GetDBField('IsPrimary')) {
- return ;
- }
-
- $sql = 'UPDATE '.$object->TableName.'
- SET IsPrimary = 0
- WHERE '.$this->getParentClause($object);
- $this->Conn->Query($sql);
-
- $object->SetDBField('Status', STATUS_ACTIVE);
- }
-
- /**
- * Makes selected file primary
- *
- * @param kEvent $event
- */
- function OnSetPrimary(&$event)
- {
- $ids = $this->StoreSelectedIDs($event);
- if (!$ids) {
- return ;
- }
-
- $object =& $event->getObject( Array('skip_autoload' => true) );
- $object->Load( array_shift($ids) );
-
- $object->SetDBField('IsPrimary', 1);
- $object->Update();
-
- $this->clearSelectedIDs($event);
- }
-
- /**
- * Don't allow to delete other user's messages
- *
- * @param kEvent $event
- */
- function customProcessing(&$event, $type)
- {
- parent::customProcessing($event, $type);
- if ($event->Name == 'OnMassDelete' && $type == 'before') {
- $ids = $event->getEventParam('ids');
- if ($ids) {
- $object =& $event->getObject();
- /* @var $object kDBItem */
-
- $primary_file_id = $this->primaryFileFound($object);
- if ($primary_file_id && ($primary_index = array_search($primary_file_id, $ids))) {
- $sql = 'SELECT COUNT(*)
- FROM '.$object->TableName.'
- WHERE (IsPrimary = 0) AND ('.$this->getParentClause($object).')';
- $non_primary_found = $this->Conn->Query($sql);
-
- if ($non_primary_found) {
- // non-primary files found for same main item -> don't delete primary file until all non-primary files are deleted
- unset($ids[$primary_index]);
- }
- }
-
- $event->setEventParam('ids', $ids);
- }
- }
- }
-
function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
$object =& $event->getObject();
if (!$this->Application->IsAdmin()) {
$object->addFilter('active_filter', '%1$s.Status = '.STATUS_ACTIVE);
}
}
-
- /**
- * Returns sql clause, that links file to it's parent item
- *
- * @param kDBItem $object
- * @return string
- */
- function getParentClause(&$object)
- {
- $parent_info = $object->getLinkedInfo($object->Special);
- return $parent_info['ForeignKey'].' = '.$parent_info['ParentId'];
- }
}
?>
\ No newline at end of file
Property changes on: branches/RC/kernel/units/files/file_eh.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/RC/kernel/units/files/files_config.php
===================================================================
--- branches/RC/kernel/units/files/files_config.php (revision 9597)
+++ branches/RC/kernel/units/files/files_config.php (revision 9598)
@@ -1,86 +1,86 @@
<?php
$config = Array (
'Prefix' => '#file',
'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'),
'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'),
'EventHandlerClass' => Array ('class' => 'FileEventHandler', 'file' => 'file_eh.php', 'build_event' => 'OnBuild'),
'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'),
'AutoLoad' => true,
'QueryString' => Array (
1 => 'id',
2 => 'page',
3 => 'event',
),
'IDField' => 'FileId',
'StatusField' => Array('Status', 'IsPrimary'),
'TitleField' => 'FileName',
'TableName' => TABLE_PREFIX.'ItemFiles',
'ParentTableKey' => 'ResourceId',
'ForeignKey' => 'ResourceId',
'AutoDelete' => true,
'AutoClone' => true,
'FilterMenu' => Array (
'Groups' => Array (
Array ('mode' => 'AND', 'filters' => Array ('show_active','show_disabled'), 'type' => WHERE_FILTER),
),
'Filters' => Array(
'show_active' => Array('label' =>'la_Active', 'on_sql' => '', 'off_sql' => '%1$s.Status != 1' ),
'show_disabled' => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Status != 0' ),
)
),
'ListSQLs' => Array (
'' => 'SELECT * FROM %s',
),
'ItemSQLs' => Array (
'' => 'SELECT * FROM %s',
),
'ListSortings' => Array (
'' => Array (
'ForcedSorting' => Array('Priority' => 'desc'),
'Sorting' => Array ('FileName' => 'asc'),
)
),
'Fields' => Array (
'FileId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'ResourceId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'FileName' => Array ('type' => 'string', 'max_len' => 255, 'required' => 1, 'not_null' => 1, 'default' => ''),
'FilePath' => Array (
'type' => 'string', 'max_len' => 255,
'formatter' => 'kUploadFormatter', 'upload_dir' => '/kernel/downloads/', 'include_path' => false,
'size_field' => 'Size', 'content_type_field' => 'MimeType', 'max_size' => 50000000,
'not_null' => 1, 'required' => 1, 'default' => ''
),
'Size' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
- 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
+ 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1),
'IsPrimary' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'Priority' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1, 'default' => '#NOW#'),
'CreatedById' => Array ('type' => 'int', 'not_null' => 1, 'default' => -1),
'MimeType' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
),
'Grids' => Array (
'Default' => Array (
'Icons' => Array ('default' => 'icon16_custom.gif', '1_0' => 'icon16_file.gif', '1_1' => 'icon16_file_primary.gif', '0_0' => 'icon16_file_disabled.gif'),
'Fields' => Array(
'FileId' => Array ('title' => 'la_col_Id' , 'data_block' => 'grid_checkbox_td', 'module' => 'In-Portal'),
'FileName' => Array ('title' => 'la_col_FileName'),
'Status' => Array ('title' => 'la_col_Status'),
),
),
),
);
?>
\ No newline at end of file
Property changes on: branches/RC/kernel/units/files/files_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/RC/kernel/units/helpers/file_helper.php
===================================================================
--- branches/RC/kernel/units/helpers/file_helper.php (nonexistent)
+++ branches/RC/kernel/units/helpers/file_helper.php (revision 9598)
@@ -0,0 +1,188 @@
+<?php
+
+ class FileHelper extends kHelper {
+
+ /**
+ * Puts existing item images (from subitem) to virtual fields (in main item)
+ *
+ * @param kCatDBItem $object
+ */
+ function LoadItemFiles(&$object)
+ {
+ $max_file_count = $this->Application->ConfigValue($object->Prefix.'_MaxImageCount'); // file count equals to image count (temporary measure)
+
+ $sql = 'SELECT *
+ FROM '.TABLE_PREFIX.'ItemFiles
+ WHERE ResourceId = '.$object->GetDBField('ResourceId').'
+ ORDER BY FileId ASC
+ LIMIT 0, '.(int)$max_file_count;
+ $item_files = $this->Conn->Query($sql);
+
+ $file_counter = 1;
+ foreach ($item_files as $item_file) {
+ $file_path = $item_file['FilePath'];
+ $object->SetDBField('File'.$file_counter, $file_path);
+ $object->SetOriginalField('File'.$file_counter, $file_path);
+ $object->Fields['File'.$file_counter]['original_field'] = $item_file['FileName'];
+ $file_counter++;
+ }
+ }
+
+ /**
+ * Saves newly uploaded images to external image table
+ *
+ * @param kCatDBItem $object
+ */
+ function SaveItemFiles(&$object)
+ {
+ $table_name = $this->Application->getUnitOption('#file', 'TableName');
+ $max_file_count = $this->Application->getUnitOption($object->Prefix, 'FileCount'); // $this->Application->ConfigValue($object->Prefix.'_MaxImageCount');
+
+ $i = 0;
+ while ($i < $max_file_count) {
+ $field = 'File'.($i + 1);
+ $field_options = $object->GetFieldOptions($field);
+
+ $file_path = $object->GetDBField($field);
+ if ($file_path) {
+ if (isset($field_options['original_field'])) {
+ $key_clause = 'FileName = '.$this->Conn->qstr($field_options['original_field']).' AND ResourceId = '.$object->GetDBField('ResourceId');
+
+ if ($object->GetDBField('Delete'.$field)) {
+ // if item was cloned, then new filename is in db (not in $image_src)
+ $sql = 'SELECT FilePath
+ FROM '.$table_name.'
+ WHERE '.$key_clause;
+ $file_path = $this->Conn->GetOne($sql);
+ if (@unlink(FULL_PATH.ITEM_FILES_PATH.$file_path)) {
+ $sql = 'DELETE FROM '.$table_name.'
+ WHERE '.$key_clause;
+ $this->Conn->Query($sql);
+ }
+ }
+ else {
+ // image record found -> update
+ $fields_hash = Array (
+ 'FilePath' => $file_path,
+ );
+
+ $this->Conn->doUpdate($fields_hash, $table_name, $key_clause);
+ }
+ }
+ else {
+ // image record not found -> create
+ $fields_hash = Array (
+ 'ResourceId' => $object->GetDBField('ResourceId'),
+ 'FileName' => $field,
+ 'Enabled' => STATUS_ACTIVE,
+ 'FilePath' => $file_path,
+ );
+
+ $this->Conn->doInsert($fields_hash, $table_name);
+ $field_options['original_field'] = $field;
+ $object->SetFieldOptions($field, $field_options);
+ }
+ }
+ $i++;
+ }
+ }
+
+ /**
+ * Preserves cloned item images/files to be rewrited with original item images/files
+ *
+ * @param Array $field_values
+ */
+ function PreserveItemFiles(&$field_values)
+ {
+ foreach ($field_values as $field_name => $field_value) {
+ if (!is_array($field_value)) continue;
+
+ if (isset($field_value['upload']) && ($field_value['error'] == UPLOAD_ERR_NO_FILE)) {
+ // this is upload field, but nothing was uploaded this time
+ unset($field_values[$field_name]);
+ }
+ }
+ }
+
+ /**
+ * Determines what image/file fields should be created (from post or just dummy fields for 1st upload)
+ *
+ * @param string $prefix
+ * @param bool $is_image
+ */
+ function createItemFiles($prefix, $is_image = false)
+ {
+ $items_info = $this->Application->GetVar($prefix);
+ if ($items_info) {
+ list ($id, $fields_values) = each($items_info);
+ $this->createUploadFields($prefix, $fields_values, $is_image);
+ }
+ else {
+ $this->createUploadFields($prefix, Array(), $is_image);
+ }
+ }
+
+ /**
+ * Dynamically creates virtual fields for item for each image/file field in submit
+ *
+ * @param string $prefix
+ * @param Array $fields_values
+ * @param bool $is_image
+ */
+ function createUploadFields($prefix, $fields_values, $is_image = false)
+ {
+ $field_options = Array (
+ 'type' => 'string',
+ 'max_len' => 240,
+ 'default' => '',
+ 'not_null' => 1,
+ );
+
+ if ($is_image) {
+ $field_options['formatter'] = 'kPictureFormatter';
+ $field_options['include_path'] = 1;
+ $fields_values['allowed_types'] = Array ('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'image/bmp');
+ $field_prefix = 'Image';
+ }
+ else {
+ $field_options['formatter'] = 'kUploadFormatter';
+ $field_options['upload_dir'] = ITEM_FILES_PATH;
+ $fields_values['allowed_types'] = Array ('application/pdf', 'application/msexcel', 'application/msword', 'application/mspowerpoint');
+ $field_prefix = 'File';
+ }
+
+ $fields = $this->Application->getUnitOption($prefix, 'Fields');
+ $virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields');
+
+ $image_count = 0;
+ foreach ($fields_values as $field_name => $field_value) {
+ if (preg_match('/^('.$field_prefix.'[\d]+|Primary'.$field_prefix.')$/', $field_name)) {
+ $fields[$field_name] = $field_options;
+ $virtual_fields[$field_name] = $field_options;
+ $virtual_fields['Delete'.$field_name] = Array ('type' => 'int', 'not_null' => 1, 'default' => 0);
+ $image_count++;
+ }
+ }
+
+ if (!$image_count) {
+ // no images found in POST -> create default image fields
+ $image_names = Array ('Primary'.$field_prefix => '');
+ $image_count = $this->Application->ConfigValue($prefix.'_MaxImageCount');
+
+ $created_count = 1;
+ while ($created_count < $image_count) {
+ $image_names[$field_prefix.$created_count] = '';
+ $created_count++;
+ }
+
+ $this->createUploadFields($prefix, $image_names, $is_image);
+ return ;
+ }
+
+ $this->Application->setUnitOption($prefix, $field_prefix.'Count', $image_count);
+ $this->Application->setUnitOption($prefix, 'Fields', $fields);
+ $this->Application->setUnitOption($prefix, 'VirtualFields', $virtual_fields);
+ }
+ }
+
+?>
\ No newline at end of file
Property changes on: branches/RC/kernel/units/helpers/file_helper.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.1.2.1
\ No newline at end of property
Index: branches/RC/kernel/units/helpers/helpers_config.php
===================================================================
--- branches/RC/kernel/units/helpers/helpers_config.php (revision 9597)
+++ branches/RC/kernel/units/helpers/helpers_config.php (revision 9598)
@@ -1,12 +1,13 @@
<?php
$config = Array (
'Prefix' => 'in-portal-helpers',
'EventHandlerClass' => Array('class' => 'kEventHandler', 'file' => '', 'build_event' => 'OnBuild'),
'RegisterClasses' => Array (
Array('pseudo' => 'SpamHelper', 'class' => 'SpamHelper','file' => 'spam_helper.php', 'build_event' => '', 'require_classes' => Array('kHelper')),
+ Array('pseudo' => 'FileHelper', 'class' => 'FileHelper','file' => 'file_helper.php', 'build_event' => '', 'require_classes' => Array('kHelper')),
),
);
?>
\ No newline at end of file
Property changes on: branches/RC/kernel/units/helpers/helpers_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.2.2.1
\ No newline at end of property
Index: branches/RC/kernel/constants.php
===================================================================
--- branches/RC/kernel/constants.php (nonexistent)
+++ branches/RC/kernel/constants.php (revision 9598)
@@ -0,0 +1,5 @@
+<?php
+
+ define('ITEM_FILES_PATH', '/kernel/downloads/');
+
+?>
\ No newline at end of file
Property changes on: branches/RC/kernel/constants.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
## -0,0 +1 ##
+1.9.8.1
\ No newline at end of property
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: branches/RC/themes/default2007/platform/elements/forms.tpl
===================================================================
--- branches/RC/themes/default2007/platform/elements/forms.tpl (revision 9597)
+++ branches/RC/themes/default2007/platform/elements/forms.tpl (revision 9598)
@@ -1,340 +1,371 @@
<inp2:m_DefineElement name="error_message">
<table class="warning-message fullwidth">
<tr>
<td width="30">
<img src="<inp2:m_TemplatesBase module="In-Portal"/>img/warning_icon.gif" width="21" height="18" alt=""/>
</td>
<td>
<inp2:m_phrase name="lu_Warning"/>
</td>
</tr>
</table>
<br />
<inp2:m_phrase name="lu_AProblemInForm"/><br />
</inp2:m_DefineElement>
<inp2:m_DefineElement name="subsection">
<div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="3" height="1" alt=""/><br /></div>
<div class="sub-section-header"><inp2:m_Phrase label="$title"/></div>
<div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="3" height="1" alt=""/><br /></div>
<br />
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_buttons" width="default">
<tr>
<td colspan="2">
<img src="<inp2:m_TemplatesBase module="In-Portal"/>img/grey_pix.gif" width="100%" height="1" align="absmiddle" alt="" />
</td>
</tr>
<tr>
<td style="width: <inp2:m_if check="m_ParamEquals" name="width" value="default">140<inp2:m_else/><inp2:m_Param name="width"/></inp2:m_if>px">
&nbsp;
</td>
<td>
<br />
<inp2:m_Param name="content"/>
<br /><br />
</td>
</tr>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_field_separator" is_last="0">
<inp2:m_if check="m_ParamEquals" name="is_last" value="0">
<tr>
<td colspan="2">
<div class="horizontal-separator"><img src="<inp2:m_TemplatesBase module="In-Portal"/>img/s.gif" width="3" height="1" alt=""/><br /></div>
</td>
</tr>
</inp2:m_if>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_field_caption" title="">
<inp2:m_inc param="tab_index" by="1"/>
<td class="field-name" nowrap>
<inp2:m_if check="m_Param" name="title">
<label for="<inp2:{$prefix}_InputName field="$field"/>">
<span <inp2:m_if check="{$prefix}_HasError" field="$field">class="field-required"</inp2:m_if>>
<inp2:m_phrase label="$title"/></span><inp2:m_if check="{$prefix}_IsRequired" field="$field"><span class="field-required"> *</span></inp2:m_if>:
</label>
<inp2:m_else/>
&nbsp;
</inp2:m_if>
</td>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_label" as_label="" currency="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td valign="top" class="field-value">
<inp2:{$prefix}_Field field="$field" as_label="$as_label" currency="$currency"/>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_label" as_label="" currency="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td valign="top" class="field-value">
<inp2:{$prefix}_Field field="$field" as_label="$as_label" currency="$currency"/>
<input type="hidden" name="<inp2:{$prefix}_InputName field="$field"/>" value="<inp2:{$prefix}_Field field="$field" db="db"/>" />
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_box" style="" maxlength="" is_last="0" title="">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<input type="text" class="input-text" name="<inp2:{$prefix}_InputName field="$field"/>" value="<inp2:{$prefix}_Field field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" maxlength="<inp2:m_param name="maxlength"/>" style="<inp2:m_param name="style"/>">
<inp2:m_if check="{$prefix}_HasParam" name="hint_label"><span class="small"><inp2:m_phrase label="$hint_label"/></span></inp2:m_if>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_password" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<input type="password" class="input-text" name="<inp2:{$prefix}_InputName field="$field"/>" id="<inp2:{$prefix}_InputName field="$field"/>" value="" tabindex="<inp2:m_get param="tab_index"/>" style="<inp2:m_param name="style"/>" />
<inp2:m_if check="{$prefix}_HasParam" name="hint_label"><span class="small"><inp2:m_phrase label="$hint_label"/></span></inp2:m_if>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_upload" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<input type="file" name="<inp2:{$prefix}_InputName field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" style="<inp2:m_param name="style"/>">
<inp2:m_if check="{$prefix}_FieldEquals" name="$field" value="" inverse="inverse">
(<inp2:{$prefix}_Field field="$field"/>)
</inp2:m_if>
<input type="hidden" name="<inp2:{$prefix}_InputName field="$field"/>[upload]" value="<inp2:{$prefix}_Field field="$field"/>" />
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_image_upload" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<inp2:m_if check="{$prefix}_Field" name="$field">
<a href="<inp2:{$prefix}_ImageSrc field="$field" MaxWidth="fullsize"/>" target="_blank">
<inp2:{$prefix}_Image field="$field" render_as="image_element" DefaultImage="platform/img/no_picture.gif" MaxWidth="thumbnail"/>
</a>
<br />
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<input type="hidden" id="<inp2:{$prefix}_InputName field="Delete{$field}"/>" name="<inp2:{$prefix}_InputName field="Delete{$field}"/>" value="0" />
<input type="checkbox" id="_cb_<inp2:{$prefix}_InputName field="Delete{$field}"/>" onchange="update_checkbox(this, document.getElementById('<inp2:{$prefix}_InputName field="Delete{$field}"/>'));">
</td>
<td>
<label for="_cb_<inp2:{$prefix}_InputName field="Delete{$field}"/>"><inp2:m_phrase name="lu_btn_DeleteImage"/></label>
</td>
</tr>
</table>
</inp2:m_if>
<input type="file" name="<inp2:{$prefix}_InputName field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" style="<inp2:m_param name="style"/>">
<input type="hidden" name="<inp2:{$prefix}_InputName field="$field"/>[upload]" value="<inp2:{$prefix}_Field field="$field"/>" />
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
+<inp2:m_DefineElement name="inp_edit_file_upload" style="" is_last="0">
+ <tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
+ <inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
+ <td class="field-value">
+ <inp2:m_if check="{$prefix}_HasError" field="$field">
+ <span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
+ </inp2:m_if>
+ <inp2:m_if check="{$prefix}_Field" name="$field">
+ <a href="<inp2:{$prefix}_DownloadFileLink field="$field"/>">
+ <inp2:{$prefix}_Field name="$field"/>
+ </a>
+ <br />
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <input type="hidden" id="<inp2:{$prefix}_InputName field="Delete{$field}"/>" name="<inp2:{$prefix}_InputName field="Delete{$field}"/>" value="0" />
+ <input type="checkbox" id="_cb_<inp2:{$prefix}_InputName field="Delete{$field}"/>" onchange="update_checkbox(this, document.getElementById('<inp2:{$prefix}_InputName field="Delete{$field}"/>'));">
+ </td>
+ <td>
+ <label for="_cb_<inp2:{$prefix}_InputName field="Delete{$field}"/>"><inp2:m_phrase name="lu_btn_DeleteFile"/></label>
+ </td>
+ </tr>
+ </table>
+ </inp2:m_if>
+ <input type="file" name="<inp2:{$prefix}_InputName field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" style="<inp2:m_param name="style"/>">
+ <input type="hidden" name="<inp2:{$prefix}_InputName field="$field"/>[upload]" value="<inp2:{$prefix}_Field field="$field"/>" />
+ </td>
+ </tr>
+ <inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
+</inp2:m_DefineElement>
+
<inp2:m_DefineElement name="inp_edit_hidden" db="">
<input type="hidden" name="<inp2:{$prefix}_InputName field="$field"/>" id="<inp2:{$prefix}_InputName field="$field"/>" value="<inp2:{$prefix}_Field field="$field" db="$db"/>" />
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_date" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="{$field}_date"/></span><br />
</inp2:m_if>
<input type="text" class="input-text" name="<inp2:{$prefix}_InputName field="{$field}_date"/>" id="<inp2:{$prefix}_InputName field="{$field}_date"/>" value="<inp2:{$prefix}_Field field="{$field}_date" format="_regional_InputDateFormat"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:{$prefix}_Format field="{$field}_date" input_format="1" edit_size="edit_size"/>" style="<inp2:m_param name="style"/>" datepickerIcon="<inp2:m_TemplatesBase module="In-Portal"/>img/calendar_icon.gif">&nbsp;<span class="small">(<inp2:{$prefix}_Format field="{$field}_date" input_format="1" human="true"/>)</span>
<script type="text/javascript">
initCalendar("<inp2:{$prefix}_InputName field="{$field}_date"/>", "<inp2:{$prefix}_Format field="{$field}_date" input_format="1"/>");
</script>
<input type="hidden" name="<inp2:{$prefix}_InputName field="{$field}_time"/>" id="<inp2:{$prefix}_InputName field="{$field}_time" input_format="1"/>" value="" />
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_time" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table-color1" even="table-color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<input type="text" name="<inp2:{$prefix}_InputName field="{$field}_time"/>" id="<inp2:{$prefix}_InputName field="{$field}_time"/>" value="<inp2:{$prefix}_Field field="{$field}_time" format="_regional_InputTimeFormat"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:{$prefix}_Format field="{$field}_time" input_format="1" edit_size="edit_size"/>" style="<inp2:m_param name="style"/>">&nbsp;
<span class="small">(<inp2:{$prefix}_Format field="{$field}_time" input_format="1" human="true"/>)</span>
<input type="hidden" name="<inp2:{$prefix}_InputName field="{$field}_date"/>" id="<inp2:{$prefix}_InputName field="{$field}_date" input_format="1"/>" value="" />
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_date_time" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<input type="text" name="<inp2:{$prefix}_InputName field="{$field}_date"/>" id="<inp2:{$prefix}_InputName field="{$field}_date"/>" value="<inp2:{$prefix}_Field field="{$field}_date" format="_regional_InputDateFormat"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:{$prefix}_Format field="{$field}_date" input_format="1" edit_size="edit_size"/>" style="<inp2:m_param name="style"/>" datepickerIcon="<inp2:m_ProjectBase/>core/admin_templates/img/calendar_icon.gif">
<span class="small">(<inp2:{$prefix}_Format field="{$field}_date" input_format="1" human="true"/>)</span>
<script type="text/javascript">
initCalendar("<inp2:{$prefix}_InputName field="{$field}_date"/>", "<inp2:{$prefix}_Format field="{$field}_date" input_format="1"/>");
</script>
&nbsp;<input type="text" name="<inp2:{$prefix}_InputName field="{$field}_time"/>" id="<inp2:{$prefix}_InputName field="{$field}_time"/>" value="<inp2:{$prefix}_Field field="{$field}_time" format="_regional_InputTimeFormat"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:{$prefix}_Format field="{$field}_time" input_format="1" edit_size="edit_size"/>" style="<inp2:m_param name="style"/>"><span class="small"> (<inp2:{$prefix}_Format field="{$field}_time" input_format="1" human="true"/>)</span>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_textarea" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<textarea class="input-textarea" tabindex="<inp2:m_get param="tab_index"/>" name="<inp2:{$prefix}_InputName field="$field"/>" cols="<inp2:m_param name="cols"/>" rows="<inp2:m_param name="rows"/>" style="<inp2:m_param name="style"/>"><inp2:{$prefix}_Field field="$field"/></textarea>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_option_item">
<option value="<inp2:m_param name="key"/>"<inp2:m_param name="selected"/>><inp2:m_param name="option"/></option>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_option_phrase">
<option value="<inp2:m_param name="key"/>"<inp2:m_param name="selected"/>><inp2:m_phrase label="$option"/></option>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_options" style="" has_empty="0" empty_value="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<select class="input-select" tabindex="<inp2:m_get param="tab_index"/>" name="<inp2:{$prefix}_InputName field="$field"/>" style="<inp2:m_param name="style"/>">
<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1" >
<inp2:{$prefix}_PredefinedOptions field="$field" block="inp_option_phrase" selected="selected" has_empty="$has_empty" empty_value="$empty_value"/>
<inp2:m_else/>
<inp2:{$prefix}_PredefinedOptions field="$field" block="inp_option_item" selected="selected" has_empty="$has_empty" empty_value="$empty_value"/>
</inp2:m_if>
</select>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_radio_item" onclick="">
<input type="radio" tabindex="<inp2:m_get param="tab_index"/>" style="<inp2:m_param name="style"/>" <inp2:m_param name="checked"/> name="<inp2:{$prefix}_InputName field="$field"/>" id="<inp2:{$prefix}_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>"><label for="<inp2:{$prefix}_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_param name="option"/></label>&nbsp;
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_radio_phrase" onclick="">
<input type="radio" tabindex="<inp2:m_get param="tab_index"/>" style="<inp2:m_param name="style"/>" <inp2:m_param name="checked"/> name="<inp2:{$prefix}_InputName field="$field"/>" id="<inp2:{$prefix}_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>"><label for="<inp2:{$prefix}_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_radio" style="" pass_tabindex="" onclick="" onchange="" use_phrases="1" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1">
<inp2:{$prefix}_PredefinedOptions field="$field" block="inp_radio_phrase" selected="checked"/>
<inp2:m_else />
<inp2:{$prefix}_PredefinedOptions field="$field" block="inp_radio_item" selected="checked"/>
</inp2:m_if>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_checkbox" style="" is_last="0">
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td>
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
<input type="hidden" id="<inp2:{$prefix}_InputName field="$field"/>" name="<inp2:{$prefix}_InputName field="$field"/>" value="<inp2:{$prefix}_Field field="$field" db="db"/>" />
<input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_<inp2:{$prefix}_InputName field="$field"/>" name="_cb_<inp2:{$prefix}_InputName field="$field"/>" <inp2:{$prefix}_Field field="$field" checked="checked" db="db"/> style="<inp2:m_param name="style"/>" onchange="update_checkbox(this, document.getElementById('<inp2:{$prefix}_InputName field="$field"/>'));">
<inp2:m_if check="{$prefix}_HasParam" name="hint_label"><inp2:m_phrase label="$hint_label"/></inp2:m_if>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="inp_edit_categories" style="" is_last="0">
<inp2:m_include template="platform/designs/categories"/>
<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
<inp2:m_RenderElement name="inp_edit_field_caption" prefix="$prefix" field="$field" title="$title"/>
<td class="field-value">
-
+
<inp2:m_if check="{$prefix}_HasError" field="$field">
<span class="field-error"><inp2:{$prefix}_Error field="$field"/></span><br />
</inp2:m_if>
-
+
<select class="input-select" tabindex="<inp2:m_get param="tab_index"/>" id="<inp2:{$prefix}_InputName field="$field"/>_select" style="<inp2:m_param name="style"/>">
<option value="0"><inp2:m_Phrase name="lu_opt_SelectCategory"/></option>
<inp2:{$prefix}_CategorySelector render_as="selector_category_element" separator="&raquo;&nbsp;"/>
</select>
-
+
<input type="button" class="button" value="<inp2:m_Phrase name="lu_Add"/>" onclick="$ItemCategories.AddCategory('&raquo;&amp;nbsp;', $delete_button, <inp2:m_GetConfig name="{$prefix}_MaxCategories"/>);"/><br />
-
-
+
+
<table class="item-categories" id="item_categories">
<tbody>
-
+
<tr>
<td colspan="2">
<strong><inp2:m_Phrase name="lu_subsection_Categories"/>:</strong>
</td>
- </tr>
-
+ </tr>
+
<inp2:{$prefix}_PrintMoreCategories render_as="more_category_element" field="$field"/>
</tbody>
</table>
<BR/>
<inp2:m_RenderElement name="inp_edit_hidden" prefix="$prefix" field="$field"/>
<script type="text/javascript">
var $delete_button = '&nbsp;&nbsp;<input type="button" class="delete-button" value="<inp2:m_Phrase name="lu_btn_Delete"/>" onclick="$ItemCategories.DeleteCategory(#CATEGORY_ID#);"/>';
var $phrases = ['<inp2:m_Phrase name="lu_error_CategoryLimitReached" escape="1"/>', '<inp2:m_Phrase name="lu_error_AlreadyAdded"/>'];
var $ItemCategories = new ItemCategories('item_categories', '<inp2:{$prefix}_InputName field="$field"/>', <inp2:m_Get name="m_cat_id"/>, $phrases);
</script>
</td>
</tr>
<inp2:m_RenderElement name="inp_edit_field_separator" is_last="$is_last"/>
</inp2:m_DefineElement>
\ No newline at end of file
Property changes on: branches/RC/themes/default2007/platform/elements/forms.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.12.2.5
\ No newline at end of property
+1.12.2.6
\ No newline at end of property
Index: branches/RC/admin/install/upgrades/inportal_upgrade_v4.2.1.sql
===================================================================
--- branches/RC/admin/install/upgrades/inportal_upgrade_v4.2.1.sql (revision 9597)
+++ branches/RC/admin/install/upgrades/inportal_upgrade_v4.2.1.sql (revision 9598)
@@ -1,23 +1,23 @@
INSERT INTO ConfigurationAdmin VALUES ('UseSmallHeader', 'la_Text_Website', 'la_config_UseSmallHeader', 'checkbox', '', '', 10.21, 0, 0);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'UseSmallHeader', '0', 'In-Portal', 'in-portal:configure_general');
ALTER TABLE Category ADD SymLinkCategoryId INT UNSIGNED NULL DEFAULT NULL AFTER `Type`, ADD INDEX (SymLinkCategoryId);
ALTER TABLE ConfigurationValues CHANGE VariableValue VariableValue TEXT NULL DEFAULT NULL;
ALTER TABLE Language ADD AdminInterfaceLang TINYINT UNSIGNED NOT NULL AFTER PrimaryLang, ADD Priority INT NOT NULL AFTER AdminInterfaceLang;
CREATE TABLE RelatedSearches (RelatedSearchId int(11) NOT NULL auto_increment, ResourceId int(11) NOT NULL default '0', Keyword varchar(255) NOT NULL default '', ItemType tinyint(4) NOT NULL default '0', Enabled tinyint(4) NOT NULL default '1', Priority int(11) NOT NULL default '0', PRIMARY KEY (RelatedSearchId), KEY Enabled (Enabled), KEY ItemType (ItemType), KEY ResourceId (ResourceId));
DELETE FROM PersistantSessionData WHERE VariableName = 'lang_columns_.';
ALTER TABLE SessionData CHANGE VariableValue VariableValue longtext NOT NULL;
INSERT INTO ConfigurationAdmin VALUES ('User_Default_Registration_Country', 'la_Text_General', 'la_config_DefaultRegistrationCountry', 'select', NULL , '=+,<SQL>SELECT DestName AS OptionName, DestId AS OptionValue FROM <PREFIX>StdDestinations WHERE DestParentId IS NULL Order BY OptionName</SQL>', 10.111, 0, 1);
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'User_Default_Registration_Country', '', 'In-Portal:Users', 'in-portal:configure_users');
INSERT INTO ConfigurationValues VALUES (DEFAULT, 'Catalog_PreselectModuleTab', 1, 'In-Portal', 'in-portal:configure_categories');
INSERT INTO ConfigurationAdmin VALUES ('Catalog_PreselectModuleTab', 'la_Text_General', 'la_config_CatalogPreselectModuleTab', 'checkbox', NULL, NULL, 10.09, 0, 1);
-CREATE TABLE ItemFiles (FileId int(11) NOT NULL auto_increment, ResourceId int(11) unsigned NOT NULL default '0', FileName varchar(255) NOT NULL default '', FilePath varchar(255) NOT NULL default '', Size int(11) NOT NULL default '0', `Status` tinyint(4) NOT NULL default '0', IsPrimary tinyint(4) NOT NULL default '0', Priority smallint(6) NOT NULL default '0', CreatedOn int(11) unsigned NOT NULL default '0', CreatedById int(11) NOT NULL default '-1', MimeType varchar(255) NOT NULL default '', PRIMARY KEY (FileId), KEY ResourceId (ResourceId));
+CREATE TABLE ItemFiles (FileId int(11) NOT NULL auto_increment, ResourceId int(11) unsigned NOT NULL default '0', FileName varchar(255) NOT NULL default '', FilePath varchar(255) NOT NULL default '', Size int(11) NOT NULL default '0', `Status` tinyint(4) NOT NULL default '0', CreatedOn int(11) unsigned NOT NULL default '0', CreatedById int(11) NOT NULL default '-1', MimeType varchar(255) NOT NULL default '', PRIMARY KEY (FileId), KEY ResourceId (ResourceId));
UPDATE Modules SET Version = '4.2.1' WHERE Name = 'Core';
UPDATE Modules SET Version = '4.2.1' WHERE Name = 'In-Portal';
\ No newline at end of file
Property changes on: branches/RC/admin/install/upgrades/inportal_upgrade_v4.2.1.sql
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.11
\ No newline at end of property
+1.1.2.12
\ No newline at end of property
Index: branches/RC/admin/install/inportal_schema.sql
===================================================================
--- branches/RC/admin/install/inportal_schema.sql (revision 9597)
+++ branches/RC/admin/install/inportal_schema.sql (revision 9598)
@@ -1,326 +1,324 @@
CREATE TABLE BanRules (
RuleId int(11) NOT NULL auto_increment,
RuleType tinyint(4) NOT NULL default '0',
ItemField varchar(255) default NULL,
ItemVerb tinyint(4) NOT NULL default '0',
ItemValue varchar(255) NOT NULL default '',
ItemType int(11) NOT NULL default '0',
Priority int(11) NOT NULL default '0',
Status tinyint(4) NOT NULL default '1',
ErrorTag varchar(255) default NULL,
PRIMARY KEY (RuleId)
)
# --------------------------------------------------------
CREATE TABLE CountCache (
ListType int(11) NOT NULL default '0',
ItemType int(11) NOT NULL default '-1',
Value int(11) NOT NULL default '0',
CountCacheId int(11) NOT NULL auto_increment,
LastUpdate int(11) NOT NULL default '0',
ExtraId varchar(50) default NULL,
TodayOnly tinyint(4) NOT NULL default '0',
PRIMARY KEY (CountCacheId)
)
# --------------------------------------------------------
CREATE TABLE Favorites (
FavoriteId int(11) NOT NULL auto_increment,
PortalUserId int(11) NOT NULL default '0',
ResourceId int(11) NOT NULL default '0',
ItemTypeId int(11) NOT NULL default '0',
Modified int(11) NOT NULL default '0',
PRIMARY KEY (FavoriteId),
UNIQUE KEY main (PortalUserId,ResourceId)
)
# --------------------------------------------------------
CREATE TABLE Images (
ImageId int(11) NOT NULL auto_increment,
ResourceId int(11) NOT NULL default '0',
Url varchar(255) NOT NULL default '',
Name varchar(255) NOT NULL default '',
AltName VARCHAR(255) NOT NULL DEFAULT '',
ImageIndex int(11) NOT NULL default '0',
LocalImage tinyint(4) NOT NULL default '1',
LocalPath varchar(240) NOT NULL default '',
Enabled int(11) NOT NULL default '1',
DefaultImg int(11) NOT NULL default '0',
ThumbUrl varchar(255) default NULL,
Priority int(11) NOT NULL default '0',
ThumbPath varchar(255) default NULL,
LocalThumb tinyint(4) NOT NULL default '1',
SameImages tinyint(4) NOT NULL default '1',
PRIMARY KEY (ImageId),
KEY ResourceId (ResourceId)
)
# --------------------------------------------------------
CREATE TABLE ItemRating (
RatingId int(11) NOT NULL auto_increment,
IPAddress varchar(255) NOT NULL default '',
CreatedOn INT UNSIGNED NULL DEFAULT NULL,
RatingValue int(11) NOT NULL default '0',
ItemId int(11) NOT NULL default '0',
PRIMARY KEY (RatingId)
)
# --------------------------------------------------------
CREATE TABLE ItemReview (
ReviewId int(11) NOT NULL auto_increment,
CreatedOn INT UNSIGNED NULL DEFAULT NULL,
ReviewText longtext NOT NULL,
Rating tinyint(3) unsigned default NULL,
IPAddress varchar(255) NOT NULL default '',
ItemId int(11) NOT NULL default '0',
CreatedById int(11) NOT NULL default '-1',
ItemType tinyint(4) NOT NULL default '0',
Priority int(11) NOT NULL default '0',
Status tinyint(4) NOT NULL default '2',
TextFormat int(11) NOT NULL default '0',
Module varchar(255) NOT NULL default '',
PRIMARY KEY (ReviewId)
)
# --------------------------------------------------------
CREATE TABLE ItemTypes (
ItemType int(11) NOT NULL default '0',
Module varchar(50) NOT NULL default '',
Prefix varchar(20) NOT NULL default '',
SourceTable varchar(100) NOT NULL default '',
TitleField varchar(50) default NULL,
CreatorField varchar(255) NOT NULL default '',
PopField varchar(255) default NULL,
RateField varchar(255) default NULL,
LangVar varchar(255) NOT NULL default '',
PrimaryItem int(11) NOT NULL default '0',
EditUrl varchar(255) NOT NULL default '',
ClassName varchar(40) NOT NULL default '',
ItemName varchar(50) NOT NULL default '',
PRIMARY KEY (ItemType),
KEY Module (Module)
)
# --------------------------------------------------------
CREATE TABLE ItemFiles (
FileId int(11) NOT NULL auto_increment,
ResourceId int(11) unsigned NOT NULL default '0',
FileName varchar(255) NOT NULL default '',
FilePath varchar(255) NOT NULL default '',
Size int(11) NOT NULL default '0',
`Status` tinyint(4) NOT NULL default '0',
- IsPrimary tinyint(4) NOT NULL default '0',
- Priority smallint(6) NOT NULL default '0',
CreatedOn int(11) unsigned NOT NULL default '0',
CreatedById int(11) NOT NULL default '-1',
MimeType varchar(255) NOT NULL default '',
PRIMARY KEY (FileId),
KEY ResourceId (ResourceId)
)
# --------------------------------------------------------
CREATE TABLE Relationship (
RelationshipId int(11) NOT NULL auto_increment,
SourceId int(11) default NULL,
TargetId int(11) default NULL,
SourceType tinyint(4) NOT NULL default '0',
TargetType tinyint(4) NOT NULL default '0',
Type int(11) NOT NULL default '0',
Enabled int(11) NOT NULL default '1',
Priority int(11) NOT NULL default '0',
PRIMARY KEY (RelationshipId),
KEY RelSource (SourceId),
KEY RelTarget (TargetId)
)
# --------------------------------------------------------
CREATE TABLE SearchConfig (
TableName varchar(40) NOT NULL default '',
FieldName varchar(40) NOT NULL default '',
SimpleSearch tinyint(4) NOT NULL default '1',
AdvancedSearch tinyint(4) NOT NULL default '1',
Description varchar(255) default NULL,
DisplayName varchar(80) default NULL,
ModuleName VARCHAR(20) NOT NULL DEFAULT 'In-Portal',
ConfigHeader varchar(255) default NULL,
DisplayOrder int(11) NOT NULL default '0',
SearchConfigId int(11) NOT NULL auto_increment,
Priority int(11) NOT NULL default '0',
FieldType varchar(20) NOT NULL default 'text',
ForeignField TEXT,
JoinClause TEXT,
IsWhere text,
IsNotWhere text,
ContainsWhere text,
NotContainsWhere text,
CustomFieldId int(11) default NULL,
PRIMARY KEY (SearchConfigId)
)
# --------------------------------------------------------
CREATE TABLE SearchLog (
SearchLogId int(11) NOT NULL auto_increment,
Keyword varchar(255) NOT NULL default '',
Indices bigint(20) NOT NULL default '0',
SearchType int(11) NOT NULL default '0',
PRIMARY KEY (SearchLogId)
)
# --------------------------------------------------------
CREATE TABLE IgnoreKeywords (
keyword varchar(20) NOT NULL default '',
PRIMARY KEY (keyword)
)
# --------------------------------------------------------
CREATE TABLE SpamControl (
ItemResourceId int(11) NOT NULL default '0',
IPaddress varchar(20) NOT NULL default '',
Expire INT UNSIGNED NULL DEFAULT NULL,
PortalUserId int(11) NOT NULL default '0',
DataType varchar(20) default NULL
)
# --------------------------------------------------------
CREATE TABLE StatItem (
StatItemId int(11) NOT NULL auto_increment,
Module varchar(20) NOT NULL default '',
ValueSQL varchar(255) default NULL,
ResetSQL varchar(255) default NULL,
ListLabel varchar(255) NOT NULL default '',
Priority int(11) NOT NULL default '0',
AdminSummary int(11) NOT NULL default '0',
PRIMARY KEY (StatItemId)
)
# --------------------------------------------------------
CREATE TABLE SuggestMail (
email varchar(255) NOT NULL default '',
sent INT UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (email)
)
# --------------------------------------------------------
CREATE TABLE SysCache (
SysCacheId int(11) NOT NULL auto_increment,
Name varchar(255) NOT NULL default '',
Value mediumtext,
Expire INT UNSIGNED NULL DEFAULT NULL,
Module varchar(20) default NULL,
Context varchar(255) default NULL,
GroupList varchar(255) NOT NULL default '',
PRIMARY KEY (SysCacheId),
KEY Name (Name)
)
# --------------------------------------------------------
CREATE TABLE TagLibrary (
TagId int(11) NOT NULL auto_increment,
name varchar(255) NOT NULL default '',
description text,
example text,
scope varchar(20) NOT NULL default 'global',
PRIMARY KEY (TagId)
)
# --------------------------------------------------------
CREATE TABLE TagAttributes (
AttrId int(11) NOT NULL auto_increment,
TagId int(11) NOT NULL default '0',
Name varchar(255) NOT NULL default '',
AttrType varchar(20) default NULL,
DefValue varchar(255) default NULL,
Description TEXT,
Required int(11) NOT NULL default '0',
PRIMARY KEY (AttrId)
)
# --------------------------------------------------------
CREATE TABLE ImportScripts (
is_id smallint(5) unsigned NOT NULL auto_increment,
is_Module varchar(50) NOT NULL default '',
is_string_id varchar(10) NOT NULL default '',
is_script varchar(100) NOT NULL default '',
is_label varchar(255) NOT NULL default '',
is_field_prefix varchar(50) NOT NULL default '',
is_requred_fields varchar(255) NOT NULL default '',
is_enabled tinyint(1) unsigned NOT NULL default '0',
is_type varchar(10) NOT NULL default '',
PRIMARY KEY (is_id)
)
# --------------------------------------------------------
CREATE TABLE StylesheetSelectors (
SelectorId int(11) NOT NULL auto_increment,
StylesheetId int(11) NOT NULL default '0',
Name varchar(255) NOT NULL default '',
SelectorName varchar(255) NOT NULL default '',
SelectorData text NOT NULL,
Description text NOT NULL,
Type tinyint(4) NOT NULL default '0',
AdvancedCSS text NOT NULL,
ParentId int(11) NOT NULL default '0',
PRIMARY KEY (SelectorId)
)
# --------------------------------------------------------
CREATE TABLE Visits (
VisitId int(11) NOT NULL auto_increment,
VisitDate int(10) unsigned NOT NULL default '0',
Referer varchar(255) NOT NULL default '',
IPAddress varchar(15) NOT NULL default '',
AffiliateId int(10) unsigned NOT NULL default '0',
PortalUserId int(11) NOT NULL default '-2',
PRIMARY KEY (VisitId),
KEY PortalUserId (PortalUserId),
KEY AffiliateId (AffiliateId)
)
# --------------------------------------------------------
CREATE TABLE ImportCache (
CacheId int(11) NOT NULL auto_increment,
CacheName varchar(255) NOT NULL default '',
VarName int(11) NOT NULL default '0',
VarValue text NOT NULL,
PRIMARY KEY (CacheId),
KEY CacheName (CacheName),
KEY VarName (VarName)
)
# --------------------------------------------------------
CREATE TABLE RelatedSearches (
RelatedSearchId int(11) NOT NULL auto_increment,
ResourceId int(11) NOT NULL default '0',
Keyword varchar(255) NOT NULL default '',
ItemType tinyint(4) NOT NULL default '0',
Enabled tinyint(4) NOT NULL default '1',
Priority int(11) NOT NULL default '0',
PRIMARY KEY (RelatedSearchId),
KEY Enabled (Enabled),
KEY ItemType (ItemType),
KEY ResourceId (ResourceId)
)
# --------------------------------------------------------
Property changes on: branches/RC/admin/install/inportal_schema.sql
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.69.2.2
\ No newline at end of property
+1.69.2.3
\ No newline at end of property
Index: branches/RC/core/units/files/file_eh.php
===================================================================
--- branches/RC/core/units/files/file_eh.php (revision 9597)
+++ branches/RC/core/units/files/file_eh.php (revision 9598)
@@ -1,166 +1,55 @@
<?php
class FileEventHandler extends kDBEventHandler {
/**
* [HOOK] Allows to apply file functionality to specific config
* When main item is created, then #file config is cloned
*
* @param kEvent $event
*/
function OnDefineFiles(&$event)
{
$clones = $this->Application->getUnitOption('#file', 'Clones');
$clones[$event->MasterEvent->Prefix.'-file'] = Array (
'ParentPrefix' => $event->MasterEvent->Prefix,
);
$this->Application->setUnitOption('#file', 'Clones', $clones);
}
/**
* Remembers user, who is created file record. Makes file primary if no other files are uploaded.
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
- parent::OnBeforeItemCreate($event);
-
- $object =& $event->getObject();
-
- $this->resetPrimary($object);
-
- if (!$this->primaryFileFound($object)) {
- $object->SetDBField('IsPrimary', 1);
- $object->SetDBField('Status', STATUS_ACTIVE);
- }
-
$object->SetDBField('CreatedById', $this->Application->RecallVar('user_id'));
}
/**
* Resets primary file mark when more then one file is marked as primary
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$object =& $event->getObject();
- $this->resetPrimary($object);
-
if (!$object->GetDBField('FileName')) {
$object->SetDBField('FileName', basename($object->GetDBField('FilePath')));
}
}
- /**
- * Checks for primary file along all files with same main item
- *
- * @param kDBItem $object
- * @return int
- */
- function primaryFileFound(&$object)
- {
- $sql = 'SELECT '.$object->IDField.'
- FROM '.$object->TableName.'
- WHERE (IsPrimary = 1) AND ('.$this->getParentClause($object).')';
- return $this->Conn->GetOne($sql);
- }
-
- /**
- * Resets primary mark from all item files
- *
- * @param kDBItem $object
- */
- function resetPrimary(&$object)
- {
- if (!$object->GetDBField('IsPrimary')) {
- return ;
- }
-
- $sql = 'UPDATE '.$object->TableName.'
- SET IsPrimary = 0
- WHERE '.$this->getParentClause($object);
- $this->Conn->Query($sql);
-
- $object->SetDBField('Status', STATUS_ACTIVE);
- }
-
- /**
- * Makes selected file primary
- *
- * @param kEvent $event
- */
- function OnSetPrimary(&$event)
- {
- $ids = $this->StoreSelectedIDs($event);
- if (!$ids) {
- return ;
- }
-
- $object =& $event->getObject( Array('skip_autoload' => true) );
- $object->Load( array_shift($ids) );
-
- $object->SetDBField('IsPrimary', 1);
- $object->Update();
-
- $this->clearSelectedIDs($event);
- }
-
- /**
- * Don't allow to delete other user's messages
- *
- * @param kEvent $event
- */
- function customProcessing(&$event, $type)
- {
- parent::customProcessing($event, $type);
- if ($event->Name == 'OnMassDelete' && $type == 'before') {
- $ids = $event->getEventParam('ids');
- if ($ids) {
- $object =& $event->getObject();
- /* @var $object kDBItem */
-
- $primary_file_id = $this->primaryFileFound($object);
- if ($primary_file_id && ($primary_index = array_search($primary_file_id, $ids))) {
- $sql = 'SELECT COUNT(*)
- FROM '.$object->TableName.'
- WHERE (IsPrimary = 0) AND ('.$this->getParentClause($object).')';
- $non_primary_found = $this->Conn->Query($sql);
-
- if ($non_primary_found) {
- // non-primary files found for same main item -> don't delete primary file until all non-primary files are deleted
- unset($ids[$primary_index]);
- }
- }
-
- $event->setEventParam('ids', $ids);
- }
- }
- }
-
function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
$object =& $event->getObject();
if (!$this->Application->IsAdmin()) {
$object->addFilter('active_filter', '%1$s.Status = '.STATUS_ACTIVE);
}
}
-
- /**
- * Returns sql clause, that links file to it's parent item
- *
- * @param kDBItem $object
- * @return string
- */
- function getParentClause(&$object)
- {
- $parent_info = $object->getLinkedInfo($object->Special);
- return $parent_info['ForeignKey'].' = '.$parent_info['ParentId'];
- }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/files/file_eh.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/RC/core/units/files/files_config.php
===================================================================
--- branches/RC/core/units/files/files_config.php (revision 9597)
+++ branches/RC/core/units/files/files_config.php (revision 9598)
@@ -1,86 +1,86 @@
<?php
$config = Array (
'Prefix' => '#file',
'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'),
'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'),
'EventHandlerClass' => Array ('class' => 'FileEventHandler', 'file' => 'file_eh.php', 'build_event' => 'OnBuild'),
'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'),
'AutoLoad' => true,
'QueryString' => Array (
1 => 'id',
2 => 'page',
3 => 'event',
),
'IDField' => 'FileId',
'StatusField' => Array('Status', 'IsPrimary'),
'TitleField' => 'FileName',
'TableName' => TABLE_PREFIX.'ItemFiles',
'ParentTableKey' => 'ResourceId',
'ForeignKey' => 'ResourceId',
'AutoDelete' => true,
'AutoClone' => true,
'FilterMenu' => Array (
'Groups' => Array (
Array ('mode' => 'AND', 'filters' => Array ('show_active','show_disabled'), 'type' => WHERE_FILTER),
),
'Filters' => Array(
'show_active' => Array('label' =>'la_Active', 'on_sql' => '', 'off_sql' => '%1$s.Status != 1' ),
'show_disabled' => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Status != 0' ),
)
),
'ListSQLs' => Array (
'' => 'SELECT * FROM %s',
),
'ItemSQLs' => Array (
'' => 'SELECT * FROM %s',
),
'ListSortings' => Array (
'' => Array (
'ForcedSorting' => Array('Priority' => 'desc'),
'Sorting' => Array ('FileName' => 'asc'),
)
),
'Fields' => Array (
'FileId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'ResourceId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'FileName' => Array ('type' => 'string', 'max_len' => 255, 'required' => 1, 'not_null' => 1, 'default' => ''),
'FilePath' => Array (
'type' => 'string', 'max_len' => 255,
'formatter' => 'kUploadFormatter', 'upload_dir' => '/kernel/downloads/', 'include_path' => false,
'size_field' => 'Size', 'content_type_field' => 'MimeType', 'max_size' => 50000000,
'not_null' => 1, 'required' => 1, 'default' => ''
),
'Size' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
- 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0),
+ 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Enabled', 0 => 'la_Disabled'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1),
'IsPrimary' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'Priority' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0),
'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1, 'default' => '#NOW#'),
'CreatedById' => Array ('type' => 'int', 'not_null' => 1, 'default' => -1),
'MimeType' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''),
),
'Grids' => Array (
'Default' => Array (
'Icons' => Array ('default' => 'icon16_custom.gif', '1_0' => 'icon16_file.gif', '1_1' => 'icon16_file_primary.gif', '0_0' => 'icon16_file_disabled.gif'),
'Fields' => Array(
'FileId' => Array ('title' => 'la_col_Id' , 'data_block' => 'grid_checkbox_td', 'module' => 'In-Portal'),
'FileName' => Array ('title' => 'la_col_FileName'),
'Status' => Array ('title' => 'la_col_Status'),
),
),
),
);
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/files/files_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.1.2.1
\ No newline at end of property
+1.1.2.2
\ No newline at end of property
Index: branches/RC/core/units/general/helpers/image_helper.php
===================================================================
--- branches/RC/core/units/general/helpers/image_helper.php (revision 9597)
+++ branches/RC/core/units/general/helpers/image_helper.php (revision 9598)
@@ -1,386 +1,295 @@
<?php
class ImageHelper extends kHelper {
/**
* Resized given image to required dimensions & saves resized image to "resized" subfolder in source image folder
*
* @param string $src_image full path to image (on server)
* @param mixed $max_width maximal allowed resized image width or false if no limit
* @param mixed $max_height maximal allowed resized image height or false if no limit
* @return string direct url to resized image
*/
function ResizeImage($src_image, $max_width, $max_height)
{
if ($max_width > 0 || $max_height > 0) {
list ($max_width, $max_height, $needs_resize) = $this->GetImageDimensions($src_image, $max_width, $max_height);
if ($needs_resize) {
$src_path = dirname($src_image);
$dst_image = preg_replace('/^'.preg_quote($src_path, '/').'(.*)\.(.*)$/', $src_path.'/resized\\1_'.$max_width.'x'.$max_height.'.\\2', $src_image);
if (!file_exists($dst_image) || filemtime($src_image) > filemtime($dst_image)) {
// resized image not available OR should be recreated due source image change
$image_resized = $this->ScaleImage($src_image, $dst_image, $max_width, $max_height);
if (!$image_resized) {
// resize failed, because of server error
$dst_image = $src_image;
}
}
// resize ok
$src_image = $dst_image;
}
}
$base_url = rtrim($this->Application->BaseURL(), '/');
return preg_replace('/^'.preg_quote(FULL_PATH, '/').'(.*)/', $base_url.'\\1', $src_image);
}
/**
* Proportionally resizes given image to destination dimensions
*
* @param string $src_image full path to source image (already existing)
* @param string $dst_image full path to destination image (will be created)
* @param int $dst_width destination image width (in pixels)
* @param int $dst_height destination image height (in pixels)
*/
function ScaleImage($src_image, $dst_image, $dst_width, $dst_height)
{
$image_info = $this->getImageInfo($src_image);
if (!$image_info) {
return false;
}
list ($dst_width, $dst_height, $resized) = $this->GetImageDimensions($src_image, $dst_width, $dst_height);
if (!$resized) {
// image dimensions are smaller or equals to required dimensions
return false;
}
if (function_exists('imagecreatefromjpeg')) {
// try to resize using GD
$resize_map = Array (
'image/jpeg' => 'imagecreatefromjpeg:imagejpeg:jpg',
'image/gif' => 'imagecreatefromgif:imagegif:gif',
'image/png' => 'imagecreatefrompng:imagepng:png',
);
$mime_type = $image_info['mime'];
if (!isset($resize_map[$mime_type])) {
return false;
}
list ($read_function, $write_function, $file_extension) = explode(':', $resize_map[$mime_type]);
$src_image_rs = @$read_function($src_image);
if ($src_image_rs) {
$dst_image_rs = imagecreatetruecolor($dst_width, $dst_height);
if ($file_extension == 'png') {
// preserve transparency of PNG images
$transparent_color = imagecolorallocate($dst_image_rs, 0, 0, 0);
imagecolortransparent($dst_image_rs, $transparent_color);
}
imagecopyresampled($dst_image_rs, $src_image_rs, 0, 0, 0, 0, $dst_width, $dst_height, $image_info[0], $image_info[1]);
return @$write_function($dst_image_rs, $dst_image, 100);
}
}
else {
// try to resize using ImageMagick
exec('/usr/bin/convert '.$src_image.' -resize '.$dst_width.'x'.$dst_height.' '.$dst_image, $shell_output, $exec_status);
return $exec_status == 0;
}
return false;
}
/**
* Returns destination image size without actual resizing (useful for <img .../> HTML tag)
*
* @param string $src_image full path to source image (already existing)
* @param int $dst_width destination image width (in pixels)
* @param int $dst_height destination image height (in pixels)
* @return Array resized image dimensions (0 - width, 1 - height)
*/
function GetImageDimensions($src_image, $dst_width, $dst_height)
{
$image_info = $this->getImageInfo($src_image);
if (!$image_info) {
return false;
}
$orig_width = $image_info[0];
$orig_height = $image_info[1];
$too_large = is_numeric($dst_width) ? ($orig_width > $dst_width) : false;
$too_large = $too_large || (is_numeric($dst_height) ? ($orig_height > $dst_height) : false);
if ($too_large) {
$width_ratio = $dst_width ? $dst_width / $orig_width : 1;
$height_ratio = $dst_height ? $dst_height / $orig_height : 1;
$ratio = min($width_ratio, $height_ratio);
$width = ceil($orig_width * $ratio);
$height = ceil($orig_height * $ratio);
}
else {
$width = $orig_width;
$height = $orig_height;
}
return Array ($width, $height, $too_large);
}
/**
* Returns image dimensions + checks if given file is existing image
*
* @param string $src_image full path to source image (already existing)
* @return mixed
*/
function getImageInfo($src_image)
{
if (!file_exists($src_image)) {
return false;
}
$image_info = @getimagesize($src_image);
if (!$image_info) {
trigger_error('Image <b>'.$src_image.'</b> <span class="debug_error">missing or invalid</span>', E_USER_WARNING);
return false;
}
return $image_info;
}
/**
* Returns maximal image size (width & height) among fields specified
*
* @param kDBItem $object
* @param string $fields
* @param string $format any format, that returns full url (e.g. files_resized:WxH, resize:WxH, full_url, full_urls)
* @return string
*/
function MaxImageSize(&$object, $fields, $format = null)
{
static $cached_sizes = Array ();
$cache_key = $object->getPrefixSpecial().'_'.$object->GetID();
if (!isset($cached_sizes[$cache_key])) {
$images = Array ();
$fields = explode(',', $fields);
foreach ($fields as $field) {
$image_data = $object->GetField($field, $format);
if (!$image_data) {
continue;
}
$images = array_merge($images, explode('|', $image_data));
}
$max_width = 0;
$max_height = 0;
$base_url = rtrim($this->Application->BaseURL(), '/');
foreach ($images as $image_url) {
$image_path = preg_replace('/^'.preg_quote($base_url, '/').'(.*)/', FULL_PATH.'\\1', $image_url);
$image_info = $this->getImageInfo($image_path);
$max_width = max($max_width, $image_info[0]);
$max_height = max($max_height, $image_info[1]);
}
$cached_sizes[$cache_key] = Array ($max_width, $max_height);
}
return $cached_sizes[$cache_key];
}
/**
- * Determines what image fields should be created (from post or just dummy fields for 1st upload)
- *
- * @param string $prefix
- */
- function createItemImages($prefix)
- {
- $items_info = $this->Application->GetVar($prefix);
- if ($items_info) {
- list ($id, $fields_values) = each($items_info);
- $this->createImageFields($prefix, $fields_values);
- }
- else {
- $this->createImageFields($prefix, Array());
- }
- }
-
- /**
- * Dynamically creates virtual fields for item for each image field in submit
- *
- * @param string $prefix
- * @param Array $fields_values
- */
- function createImageFields($prefix, $fields_values)
- {
- $field_options = Array (
- 'type' => 'string',
- 'formatter' => 'kPictureFormatter',
-// 'skip_empty' => 1,
- 'max_len' => 240,
- 'default' => '',
- 'not_null' => 1,
- 'include_path' => 1,
- 'allowed_types' => Array ('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'image/bmp'),
- 'error_msgs' => Array (
- 'bad_file_format' => '!la_error_InvalidFileFormat!',
- 'bad_file_size' => '!la_error_FileTooLarge!',
- 'cant_save_file' => '!la_error_cant_save_file!'
- ),
- );
-
- $fields = $this->Application->getUnitOption($prefix, 'Fields');
- $virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields');
-
- $image_count = 0;
- foreach ($fields_values as $field_name => $field_value) {
- if (preg_match('/^(Image[\d]+|PrimaryImage)$/', $field_name)) {
- $fields[$field_name] = $field_options;
- $virtual_fields[$field_name] = $field_options;
- $virtual_fields['Delete'.$field_name] = Array ('type' => 'int', 'not_null' => 1, 'default' => 0);
- $image_count++;
- }
- }
-
- if (!$image_count) {
- // no images found in POST -> create default image fields
- $image_names = Array ('PrimaryImage' => '');
- $image_count = $this->Application->ConfigValue($prefix.'_MaxImageCount');
-
- $created_count = 1;
- while ($created_count < $image_count) {
- $image_names['Image'.$created_count] = '';
- $created_count++;
- }
-
- $this->createImageFields($prefix, $image_names);
- return ;
- }
-
- $this->Application->setUnitOption($prefix, 'ImageCount', $image_count);
- $this->Application->setUnitOption($prefix, 'Fields', $fields);
- $this->Application->setUnitOption($prefix, 'VirtualFields', $virtual_fields);
- }
-
- /**
* Puts existing item images (from subitem) to virtual fields (in main item)
*
* @param kCatDBItem $object
*/
function LoadItemImages(&$object)
{
$max_image_count = $this->Application->ConfigValue($object->Prefix.'_MaxImageCount');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'Images
WHERE ResourceId = '.$object->GetDBField('ResourceId').'
ORDER BY ImageId ASC
LIMIT 0, '.(int)$max_image_count;
$item_images = $this->Conn->Query($sql);
$image_counter = 1;
foreach ($item_images as $item_image) {
$image_path = $item_image['ThumbPath'];
if ($item_image['DefaultImg'] == 1 || $item_image['Name'] == 'main') {
// process primary image separately
$object->SetDBField('PrimaryImage', $image_path);
$object->SetOriginalField('PrimaryImage', $image_path);
$object->Fields['PrimaryImage']['original_field'] = $item_image['Name'];
continue;
}
$object->SetDBField('Image'.$image_counter, $image_path);
$object->SetOriginalField('Image'.$image_counter, $image_path);
$object->Fields['Image'.$image_counter]['original_field'] = $item_image['Name'];
$image_counter++;
}
}
/**
* Saves newly uploaded images to external image table
*
* @param kCatDBItem $object
*/
function SaveItemImages(&$object)
{
$table_name = $this->Application->getUnitOption('img', 'TableName');
$max_image_count = $this->Application->getUnitOption($object->Prefix, 'ImageCount'); // $this->Application->ConfigValue($object->Prefix.'_MaxImageCount');
$i = 0;
while ($i < $max_image_count) {
$field = $i ? 'Image'.$i : 'PrimaryImage';
$field_options = $object->GetFieldOptions($field);
$image_src = $object->GetDBField($field);
if ($image_src) {
if (isset($field_options['original_field'])) {
$key_clause = 'Name = '.$this->Conn->qstr($field_options['original_field']).' AND ResourceId = '.$object->GetDBField('ResourceId');
if ($object->GetDBField('Delete'.$field)) {
// if item was cloned, then new filename is in db (not in $image_src)
$sql = 'SELECT ThumbPath
FROM '.$table_name.'
WHERE '.$key_clause;
$image_src = $this->Conn->GetOne($sql);
if (@unlink(FULL_PATH.$image_src)) {
$sql = 'DELETE FROM '.$table_name.'
WHERE '.$key_clause;
$this->Conn->Query($sql);
}
}
else {
// image record found -> update
$fields_hash = Array (
'ThumbPath' => $image_src,
);
$this->Conn->doUpdate($fields_hash, $table_name, $key_clause);
}
}
else {
// image record not found -> create
$fields_hash = Array (
'ResourceId' => $object->GetDBField('ResourceId'),
'Name' => $field,
'AltName' => $field,
'Enabled' => STATUS_ACTIVE,
'DefaultImg' => $i ? 0 : 1, // first image is primary, others not primary
'ThumbPath' => $image_src,
);
$this->Conn->doInsert($fields_hash, $table_name);
$field_options['original_field'] = $field;
$object->SetFieldOptions($field, $field_options);
}
}
$i++;
}
}
-
- /**
- * Preserves cloned item images to be rewrited with original item images
- *
- * @param Array $field_values
- */
- function PreserveItemImages(&$field_values)
- {
- foreach ($field_values as $field_name => $field_value) {
- if (!is_array($field_value)) continue;
-
- if (isset($field_value['upload']) && ($field_value['error'] == UPLOAD_ERR_NO_FILE)) {
- // this is upload field, but nothing was uploaded this time
- unset($field_values[$field_name]);
- }
- }
- }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/helpers/image_helper.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.6.2.4
\ No newline at end of property
+1.6.2.5
\ No newline at end of property
Index: branches/RC/core/units/general/cat_tag_processor.php
===================================================================
--- branches/RC/core/units/general/cat_tag_processor.php (revision 9597)
+++ branches/RC/core/units/general/cat_tag_processor.php (revision 9598)
@@ -1,636 +1,643 @@
<?php
class kCatDBTagProcessor extends kDBTagProcessor {
/**
* Permission Helper
*
* @var kPermissionsHelper
*/
var $PermHelper = null;
function kCatDBTagProcessor()
{
parent::kDBTagProcessor();
$this->PermHelper = $this->Application->recallObject('PermissionsHelper');
}
function ItemIcon($params)
{
$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
$icons =& $grids[ $params['grid'] ]['Icons'];
$status_fields = $this->Application->getUnitOption($this->Prefix,'StatusField');
if (!$status_fields) return $icons['default'];
$value = $object->GetDBField($status_fields[0]); // sets base status icon
/* @var $object kDBItem */
if ($value == STATUS_ACTIVE) {
if( $object->HasField('IsPop') && $object->GetDBField('IsPop') ) $value = 'POP';
if( $object->HasField('IsHot') && $object->GetDBField('IsHot') ) $value = 'HOT';
if( $object->HasField('IsNew') && $object->GetDBField('IsNew') ) $value = 'NEW';
if( $object->HasField('EditorsPick') && $object->GetDBField('EditorsPick') ) $value = 'PICK';
}
return isset($icons[$value]) ? $icons[$value] : $icons['default'];
}
/**
* Allows to create valid mod-rewrite compatible link to module item
*
* @param Array $params
* @param string $id_prefix
* @return string
*/
function ItemLink($params, $id_prefix = null)
{
if (!isset($params['pass'])) {
$params['pass'] = 'm,'.$this->Prefix;
}
$item_id = isset($params[$id_prefix.'_id']) && $params[$id_prefix.'_id'];
if (!$item_id) {
$item_id = $this->Application->GetVar($this->getPrefixSpecial().'_id');
if (!$item_id) {
$item_id = $this->Application->GetVar($this->Prefix.'_id');
}
}
$params[$this->Prefix.'_id'] = $item_id;
$object =& $this->getObject($params);
$params['m_cat_id'] = $object->GetDBField('CategoryId');
$params['pass_category'] = 1;
return $this->Application->ProcessParsedTag('m', 't', $params);
}
function CategoryPath($params)
{
if ($this->Application->IsAdmin()) {
// path for module root category in admin
if (!isset($params['cat_id'])) {
$params['cat_id'] = $this->Application->RecallVar($params['session_var'], 0);
}
}
else {
// path for category item category in front-end
$object =& $this->getObject($params);
$params['cat_id'] = $object->GetDBField('CategoryId');
}
return $this->Application->ProcessParsedTag('c', 'CategoryPath', $params);
}
function BuildListSpecial($params)
{
if ($this->Special != '') return $this->Special;
if ( isset($params['parent_cat_id']) ) {
$parent_cat_id = $params['parent_cat_id'];
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
}
$recursive = isset($params['recursive']);
$list_unique_key = $this->getUniqueListKey($params).$recursive;
if ($list_unique_key == '') {
return parent::BuildListSpecial($params);
}
return crc32($parent_cat_id.$list_unique_key);
}
function CatalogItemCount($params)
{
$object =& $this->GetList($params);
if (!$object->Counted) {
$object->CountRecs();
}
return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' / '.$object->NoFilterCount : $object->RecordsCount;
}
function ListReviews($params)
{
$prefix = $this->Prefix.'-rev';
$review_tag_processor =& $this->Application->recallObject($prefix.'.item_TagProcessor');
return $review_tag_processor->PrintList($params);
}
function ReviewCount($params)
{
$review_tag_processor =& $this->Application->recallObject('rev.item_TagProcessor');
return $review_tag_processor->TotalRecords($params);
}
function InitCatalogTab($params)
{
$tab_params['mode'] = $this->Application->GetVar('tm'); // single/multi selection possible
$tab_params['special'] = $this->Application->GetVar('ts'); // use special for this tab
$tab_params['dependant'] = $this->Application->GetVar('td'); // is grid dependant on categories grid
// set default params (same as in catalog)
if ($tab_params['mode'] === false) $tab_params['mode'] = 'multi';
if ($tab_params['special'] === false) $tab_params['special'] = '';
if ($tab_params['dependant'] === false) $tab_params['dependant'] = 'yes';
// pass params to block with tab content
$params['name'] = $params['render_as'];
$params['prefix'] = trim($this->Prefix.'.'.($tab_params['special'] ? $tab_params['special'] : $this->Special), '.');
$params['cat_prefix'] = trim('c.'.($tab_params['special'] ? $tab_params['special'] : $this->Special), '.');
$params['tab_mode'] = $tab_params['mode'];
$params['tab_dependant'] = $tab_params['dependant'];
$params['show_category'] = $tab_params['special'] == 'showall' ? 1 : 0; // this is advanced view -> show category name
return $this->Application->ParseBlock($params, 1);
}
/**
* Show CachedNavbar of current item primary category
*
* @param Array $params
* @return string
*/
function CategoryName($params)
{
// show category cachednavbar of
$object =& $this->getObject($params);
$category_id = isset($params['cat_id']) ? $params['cat_id'] : $object->GetDBField('CategoryId');
$category_path = $this->Application->getCache('category_paths', $category_id);
if ($category_path === false) {
// not chached
if ($category_id > 0) {
$category_path = trim($this->CategoryName( Array('cat_id' => 0) ).' > '.str_replace('&|&', ' > ', $object->GetDBField('CachedNavbar')), ' > ');
}
else {
$category_path = $this->Application->Phrase( $this->Application->ConfigValue('Root_Name') );
}
$this->Application->setCache('category_paths', $category_id, $category_path);
}
return $category_path;
}
/**
* Allows to determine if original value should be shown
*
* @param Array $params
* @return bool
*/
function DisplayOriginal($params)
{
// original id found & greather then zero + show original
$display_original = isset($params['display_original']) && $params['display_original'];
$owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
$object =& $this->getObject($params);
$perm_value = $this->PermHelper->ModifyCheckPermission($object->GetDBField($owner_field), $object->GetDBField('CategoryId'), $this->Prefix);
return $display_original && ($perm_value == 1) && $this->Application->GetVar($this->Prefix.'.original_id');
}
/**
* Checks if user have one of required permissions
*
* @param Array $params
* @return bool
*/
function HasPermission($params)
{
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$params['raise_warnings'] = 0;
$object =& $this->getObject($params);
/* @var $object kCatDBItem */
// 1. category restriction
$params['cat_id'] = $object->isLoaded() ? $object->GetDBField('ParentPath') : $this->Application->GetVar('m_cat_id');
// 2. owner restriction
$owner_field = $this->Application->getUnitOption($this->Prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
$is_owner = $object->GetDBField($owner_field) == $this->Application->RecallVar('user_id');
return $perm_helper->TagPermissionCheck($params, $is_owner);
}
/**
* Creates link to current category or to module root category, when current category is home
*
* @param Array $params
* @return string
*/
function SuggestItemLink($params)
{
if (!isset($params['cat_id'])) {
$params['cat_id'] = $this->Application->GetVar('m_cat_id');
}
if ($params['cat_id'] == 0) {
$params['cat_id'] = $this->Application->findModule('Var', $this->Prefix, 'RootCat');
}
return $this->Application->ProcessParsedTag('c', 'CategoryLink', $params);
}
/**
* Allows to detect if item has any additional images available
*
* @param Array $params
* @return string
*/
function HasAdditionalImages($params)
{
$object =& $this->getObject($params);
$sql = 'SELECT ImageId
FROM '.$this->Application->getUnitOption('img', 'TableName').'
WHERE ResourceId = '.$object->GetDBField('ResourceId').' AND DefaultImg != 1 AND Enabled = 1';
return $this->Conn->GetOne($sql) ? 1 : 0;
}
/**
* Checks that item is pending
*
* @param Array $params
* @return bool
*/
function IsPending($params)
{
$object =& $this->getObject($params);
$pending_status = Array (STATUS_PENDING, STATUS_PENDING_EDITING);
return in_array($object->GetDBField('Status'), $pending_status);
}
function IsFavorite($params)
{
static $favorite_status = Array ();
$object =& $this->getObject($params);
/* @var $object kDBList */
if (!isset($favorite_status[$this->Special])) {
$resource_ids = $object->GetCol('ResourceId');
$user_id = $this->Application->RecallVar('user_id');
$sql = 'SELECT FavoriteId, ResourceId
FROM '.$this->Application->getUnitOption('fav', 'TableName').'
WHERE (PortalUserId = '.$user_id.') AND (ResourceId IN ('.implode(',', $resource_ids).'))';
$favorite_status[$this->Special] = $this->Conn->GetCol($sql, 'ResourceId');
}
return isset($favorite_status[$this->Special][$object->GetDBField('ResourceId')]);
}
/**
* Returns item's editors pick status (using not formatted value)
*
* @param Array $params
* @return bool
*/
function IsEditorsPick($params)
{
$object =& $this->getObject($params);
return $object->GetDBField('EditorsPick') == 1;
}
function FavoriteToggleLink($params)
{
$fav_prefix = $this->Prefix.'-fav';
$params['pass'] = implode(',', Array('m', $this->Prefix, $fav_prefix));
$params[$fav_prefix.'_event'] = 'OnFavoriteToggle';
return $this->ItemLink($params);
}
/**
* Checks if item is passed in url
*
* @param Array $params
* @return bool
*/
function ItemAvailable($params)
{
return $this->Application->GetVar($this->getPrefixSpecial().'_id') > 0;
}
function SortingSelected($params)
{
$list =& $this->GetList($params);
$user_sorting_start = $this->getUserSortIndex();
$sorting = strtolower($list->GetOrderField($user_sorting_start).'|'.$list->GetOrderDirection($user_sorting_start));
if ($sorting == strtolower($params['sorting'])) return $params['selected'];
}
function CombinedSortingDropDownName($params)
{
return $this->Prefix.'_CombinedSorting';
}
/**
* Prepares name for field with event in it (used only on front-end)
*
* @param Array $params
* @return string
*/
function SubmitName($params)
{
return 'events['.$this->Prefix.']['.$params['event'].']';
}
/**
* Returns prefix + any word (used for shared between categories per page settings)
*
* @param Array $params
* @return string
*/
function VarName($params)
{
return $this->Prefix.'_'.$params['type'];
}
/**
* Checks if we are viewing module root category
*
* @param Array $params
* @return bool
*/
function IsModuleHome($params)
{
$root_category = $this->Application->findModule('Var', $this->Prefix, 'RootCat');
return $root_category == $this->Application->GetVar('m_cat_id');
}
/**
* Dynamic votes indicator
*
* @param Array $params
*
* @return string
*/
function VotesIndicator($params)
{
$blocks_params = $this->prepareTagParams($params);
$blocks_params['name'] = $params['render_as'];
$object =& $this->getObject($params);
/* @var $object kDBItem */
if ($this->Application->ConfigValue('UseFloatRating')) {
$rating = $object->GetDBField('CachedRating');
$float_rating = floor(($rating - floor($rating)) / 0.25) * 0.25;
}
else {
$rating = round( $object->GetDBField('CachedRating') );
$float_rating = 0;
}
$i = 1;
$ret = '';
while ($i <= 5) {
$blocks_params['number'] = $i;
$blocks_params['active'] = $rating >= $i ? 1 : 0;
if ($rating > $i - 1 && $rating < $i && $float_rating > 0) {
$blocks_params['active'] = 1;
$blocks_params['float_rating'] = $float_rating;
}
else {
$blocks_params['float_rating'] = '';
}
$ret .= trim($this->Application->ParseBlock($blocks_params));
$i++;
}
return $ret;
}
function RelevanceIndicator($params)
{
$object =& $this->getObject($params);
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SELECT Relevance
FROM '.$search_results_table.'
WHERE ResourceId = '.$object->GetDBField('ResourceId');
$percents_off = (int)(100 - (100 * $this->Conn->GetOne($sql)));
$percents_off = ($percents_off < 0) ? 0 : $percents_off;
if ($percents_off) {
$params['percent_off'] = $percents_off;
$params['percent_on'] = 100 - $percents_off;
$params['name'] = $this->SelectParam($params, 'relevance_normal_render_as,block_relevance_normal');
}
else {
$params['name'] = $this->SelectParam($params, 'relevance_full_render_as,block_relevance_full');
}
return $this->Application->ParseBlock($params);
}
function SearchResultField($params)
{
$ret = $this->Field($params);
$keywords = unserialize( $this->Application->RecallVar('highlight_keywords') );
$opening = $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'highlight_opening_render_as,block_highlight_opening')) );
$closing = $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'highlight_closing_render_as,block_highlight_closing')) );
foreach ($keywords as $index => $keyword) {
$keywords[$index] = preg_quote($keyword, '/');
}
return preg_replace('/('.implode('|', $keywords).')/i', $opening.'\\1'.$closing, $ret);
}
function AdvancedSearchForm($params)
{
$search_table = $this->Application->getUnitOption('confs', 'TableName');
$module_name = $this->Application->findModule('Var', $this->Prefix, 'Name');
$sql = 'SELECT *
FROM '.$search_table.'
WHERE (ModuleName = '.$this->Conn->qstr($module_name).') AND (AdvancedSearch = 1)
ORDER BY DisplayOrder';
$search_config = $this->Conn->Query($sql);
$ret = '';
foreach ($search_config as $record) {
$params['name'] = $this->SelectParam($params, 'and_or_render_as,and_or_block');
$params['field'] = $record['FieldName'];
$params['andor'] = $this->Application->ParseBlock($params);
$params['name'] = $this->SelectParam($params, $record['FieldType'].'_render_as,'.$record['FieldType'].'_block');
$params['caption'] = $this->Application->Phrase($record['DisplayName']);
$ret .= $this->Application->ParseBlock($params);
}
return $ret;
}
/**
* Returns last modification date of items in category / system
*
* @param Array $params
* @return string
*/
function LastUpdated($params)
{
$category_id = $this->Application->GetVar('m_cat_id');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
if (isset($params['local']) && $params['local'] && $category_id > 0) {
// scan only current category & it's children
$sql = 'SELECT TreeLeft, TreeRight
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$category_id;
$tree_info = $this->Conn->GetRow($sql);
$sql = 'SELECT MAX(item_table.Modified) AS ModDate, MAX(item_table.CreatedOn) AS NewDate
FROM '.$table_name.' item_table
LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON (item_table.ResourceId = ci.ItemResourceId)
LEFT JOIN '.TABLE_PREFIX.'Category c ON c.CategoryId = ci.CategoryId
WHERE c.TreeLeft BETWEEN '.$tree_info['TreeLeft'].' AND '.$tree_info['TreeRight'];
}
else {
// scan all categories in system
$sql = 'SELECT MAX(Modified) AS ModDate, MAX(CreatedOn) AS NewDate
FROM '.$table_name;
}
$row_data = $this->Conn->GetRow($sql);
if (!$row_data) {
return '';
}
$date = $row_data[ $row_data['NewDate'] > $row_data['ModDate'] ? 'NewDate' : 'ModDate' ];
// format date
$format = isset($params['format']) ? $params['format'] : '_regional_DateTimeFormat';
if (preg_match("/_regional_(.*)/", $format, $regs)) {
$lang =& $this->Application->recallObject('lang.current');
if ($regs[1] == 'DateTimeFormat') {
// combined format
$format = $lang->GetDBField('DateFormat').' '.$lang->GetDBField('TimeFormat');
}
else {
// simple format
$format = $lang->GetDBField($regs[1]);
}
}
return adodb_date($format, $date);
}
/**
* Counts category item count in system (not category-dependent)
*
* @param Array $params
* @return int
*/
function ItemCount($params)
{
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
$today_only = isset($params['today']) && $params['today'];
return $count_helper->ItemCount($this->Prefix, $today_only);
}
function CategorySelector($params)
{
$category_id = isset($params['category_id']) && is_numeric($params['category_id']) ? $params['category_id'] : false;
if ($category_id === false) {
// if category id not given use module root category
$category_id = $this->Application->findModule('Var', $this->Prefix, 'RootCat');
}
$id_field = $this->Application->getUnitOption('c', 'IDField');
$title_field = $this->Application->getUnitOption('c', 'TitleField');
$table_name = $this->Application->getUnitOption('c', 'TableName');
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
list ($view_perm, $view_filter) = $count_helper->GetPermissionClause('c', 'perm_cache');
// get category list (permission based)
$sql = 'SELECT c.'.$title_field.', c.'.$id_field.'
FROM '.$table_name.' c
INNER JOIN '.TABLE_PREFIX.'PermCache perm_cache ON c.CategoryId = perm_cache.CategoryId
WHERE (ParentId = '.$category_id.') AND ('.$view_filter.') AND (perm_cache.PermId = '.$view_perm.') AND (c.Status = '.STATUS_ACTIVE.')
ORDER BY c.'.$title_field.' ASC';
$categories = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$block_params['strip_nl'] = 2;
$ret = '';
foreach ($categories as $category_id => $category_name) {
// print category
$block_params['separator'] = isset($params['category_id']) ? $params['separator'] : ''; // return original separator, remove separator for top level categories
$block_params['category_id'] = $category_id;
$block_params['category_name'] = $category_name;
$ret .= $this->Application->ParseBlock($block_params);
// print it's children
$block_params['separator'] = '&nbsp;&nbsp;&nbsp;'.$params['separator'];
$ret .= $this->CategorySelector($block_params);
}
return $ret;
}
function PrintMoreCategories($params)
{
$object =& $this->getObject();
/* @var $object kDBItem */
$category_ids = $this->Field($params);
if (!$category_ids) {
return '';
}
$category_ids = explode('|', substr($category_ids, 1, -1));
$id_field = $this->Application->getUnitOption('c', 'IDField');
$title_field = $this->Application->getUnitOption('c', 'TitleField');
$table_name = $this->Application->getUnitOption('c', 'TableName');
$sql = 'SELECT '.$title_field.', '.$id_field.'
FROM '.$table_name.'
WHERE '.$id_field.' IN ('.implode(',', $category_ids).')';
$categories = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$ret = '';
foreach ($categories as $category_id => $category_name) {
$block_params['category_id'] = $category_id;
$block_params['category_name'] = $category_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
+
+ function DownloadFileLink($params)
+ {
+ $params[$this->getPrefixSpecial().'_event'] = 'OnDownloadFile';
+
+ return $this->ItemLink($params);
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/cat_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.38.2.7
\ No newline at end of property
+1.38.2.8
\ No newline at end of property
Index: branches/RC/core/units/general/cat_event_handler.php
===================================================================
--- branches/RC/core/units/general/cat_event_handler.php (revision 9597)
+++ branches/RC/core/units/general/cat_event_handler.php (revision 9598)
@@ -1,2294 +1,2342 @@
<?php
$application =& kApplication::Instance();
$application->Factory->includeClassFile('kDBEventHandler');
class kCatDBEventHandler extends kDBEventHandler {
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
- 'OnExport' => Array('self' => 'view|advanced:export'),
- 'OnExportBegin' => Array('self' => 'view|advanced:export'),
- 'OnSaveSettings' => Array('self' => 'add|edit|advanced:import'),
- 'OnBeforeDeleteOriginal' => Array('self' => 'edit|advanced:approve'),
+ 'OnExport' => Array('self' => 'view|advanced:export'),
+ 'OnExportBegin' => Array('self' => 'view|advanced:export'),
+ 'OnSaveSettings' => Array('self' => 'add|edit|advanced:import'),
+ 'OnBeforeDeleteOriginal' => Array('self' => 'edit|advanced:approve'),
- 'OnCancelAction' => Array('self' => true),
- );
+ 'OnDownloadFile' => Array('self' => 'view'),
+
+ 'OnCancelAction' => Array('self' => true),
+ );
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Load item if id is available
*
* @param kEvent $event
*/
function LoadItem(&$event)
{
$object =& $event->getObject();
$id = $this->getPassedID($event);
if ($object->Load($id)) {
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_id', $object->GetID() );
$use_pending_editing = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($use_pending_editing && $event->Special != 'original') {
$this->Application->SetVar($event->Prefix.'.original_id', $object->GetDBField('OrgId'));
}
}
else {
$object->setID($id);
}
}
/**
* Checks permissions of user
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
if (!$this->Application->IsAdmin()) {
if ($event->Name == 'OnSetSortingDirect') {
// allow sorting on front event without view permission
return true;
}
}
if ($event->Name == 'OnExport') {
// save category_id before doing export
$this->Application->LinkVar('m_cat_id');
}
if ($event->Name == 'OnNew' && preg_match('/(.*)\/import$/', $this->Application->GetVar('t'), $rets)) {
// redirect to item import template, where permission (import) category will be chosen)
$root_category = $this->Application->findModule('Path', $rets[1].'/', 'RootCat');
$this->Application->StoreVar('m_cat_id', $root_category);
}
$check_events = Array ('OnEdit', 'OnSave', 'OnMassDelete');
if (in_array($event->Name, $check_events)) {
// check each id from selected individually and only if all are allowed proceed next
if ($event->Name == 'OnSave') {
$selected_ids = implode(',', $this->getSelectedIDs($event, true));
if (!$selected_ids) {
$selected_ids = 0; // when saving newly created item (OnPreCreate -> OnPreSave -> OnSave)
}
}
else {
$selected_ids = implode(',', $this->StoreSelectedIDs($event));
}
$perm_value = true;
if (strlen($selected_ids)) {
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$items = $perm_helper->GetCategoryItemData($event->Prefix, $selected_ids);
$check_method = ($event->Name == 'OnMassDelete') ? 'DeleteCheckPermission' : 'ModifyCheckPermission';
foreach ($items as $item_id => $item_data) {
if ($perm_helper->$check_method($item_data['CreatedById'], $item_data['CategoryId'], $event->Prefix) == 0) {
// one of items selected has no permission
$perm_value = false;
break;
}
}
if (!$perm_value) {
$event->status = erPERM_FAIL;
}
}
else {
trigger_error('IDs not passed to '.$event->getPrefixSpecial().':CheckPermission', E_USER_WARNING);
}
return $perm_value;
}
return parent::CheckPermission($event);
}
/**
* Add selected items to clipboard with mode = COPY (CLONE)
*
* @param kEvent $event
*/
function OnCopy(&$event)
{
$this->Application->RemoveVar('clipboard');
$clipboard_helper =& $this->Application->recallObject('ClipboardHelper');
$clipboard_helper->setClipboard($event, 'copy', $this->StoreSelectedIDs($event));
}
/**
* Add selected items to clipboard with mode = CUT
*
* @param kEvent $event
*/
function OnCut(&$event)
{
$this->Application->RemoveVar('clipboard');
$clipboard_helper =& $this->Application->recallObject('ClipboardHelper');
$clipboard_helper->setClipboard($event, 'cut', $this->StoreSelectedIDs($event));
}
/**
* Performs category item paste
*
* @param kEvent $event
*/
function OnPaste(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$clipboard_data = $event->getEventParam('clipboard_data');
if (!$clipboard_data['cut'] && !$clipboard_data['copy']) {
return false;
}
if ($clipboard_data['copy']) {
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$this->Application->SetVar('ResetCatBeforeClone', 1);
$temp->CloneItems($event->Prefix, $event->Special, $clipboard_data['copy']);
}
if ($clipboard_data['cut']) {
$object =& $this->Application->recallObject($event->getPrefixSpecial().'.item', $event->Prefix, Array('skip_autoload' => true));
foreach ($clipboard_data['cut'] as $id) {
$object->Load($id);
$object->MoveToCat();
}
}
}
/**
* Return type clauses for list bulding on front
*
* @param kEvent $event
* @return Array
*/
function getTypeClauses(&$event)
{
$types = $event->getEventParam('types');
$types = $types ? explode(',', $types) : Array ();
$except_types = $event->getEventParam('except');
$except_types = $except_types ? explode(',', $except_types) : Array ();
$type_clauses = Array();
$user_id = $this->Application->RecallVar('user_id');
$owner_field = $this->getOwnerField($event->Prefix);
$type_clauses['my_items']['include'] = '%1$s.'.$owner_field.' = '.$user_id;
$type_clauses['my_items']['except'] = '%1$s.'.$owner_field.' <> '.$user_id;
$type_clauses['my_items']['having_filter'] = false;
$type_clauses['pick']['include'] = '%1$s.EditorsPick = 1 AND '.TABLE_PREFIX.'CategoryItems.PrimaryCat = 1';
$type_clauses['pick']['except'] = '%1$s.EditorsPick! = 1 AND '.TABLE_PREFIX.'CategoryItems.PrimaryCat = 1';
$type_clauses['pick']['having_filter'] = false;
$type_clauses['hot']['include'] = '`IsHot` = 1 AND PrimaryCat = 1';
$type_clauses['hot']['except'] = '`IsHot`! = 1 AND PrimaryCat = 1';
$type_clauses['hot']['having_filter'] = true;
$type_clauses['pop']['include'] = '`IsPop` = 1 AND PrimaryCat = 1';
$type_clauses['pop']['except'] = '`IsPop`! = 1 AND PrimaryCat = 1';
$type_clauses['pop']['having_filter'] = true;
$type_clauses['new']['include'] = '`IsNew` = 1 AND PrimaryCat = 1';
$type_clauses['new']['except'] = '`IsNew`! = 1 AND PrimaryCat = 1';
$type_clauses['new']['having_filter'] = true;
$type_clauses['displayed']['include'] = '';
$displayed = $this->Application->GetVar($event->Prefix.'_displayed_ids');
if ($displayed) {
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$type_clauses['displayed']['except'] = '%1$s.'.$id_field.' NOT IN ('.$displayed.')';
}
else {
$type_clauses['displayed']['except'] = '';
}
$type_clauses['displayed']['having_filter'] = false;
if (in_array('search', $types) || in_array('search', $except_types)) {
$event_mapping = Array(
'simple' => 'OnSimpleSearch',
'subsearch' => 'OnSubSearch',
'advanced' => 'OnAdvancedSearch');
if($this->Application->GetVar('INPORTAL_ON') && $this->Application->GetVar('Action') == 'm_simple_subsearch')
{
$type = 'subsearch';
}
else
{
$type = $this->Application->GetVar('search_type') ? $this->Application->GetVar('search_type') : 'simple';
}
if($keywords = $event->getEventParam('keyword_string')) // processing keyword_string param of ListProducts tag
{
$this->Application->SetVar('keywords', $keywords);
$type = 'simple';
}
$search_event = $event_mapping[$type];
$this->$search_event($event);
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if ($this->Conn->Query($sql)) {
$search_res_ids = $this->Conn->GetCol('SELECT ResourceId FROM '.$search_table);
}
if (isset($search_res_ids) && $search_res_ids) {
$type_clauses['search']['include'] = '%1$s.ResourceId IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1';
$type_clauses['search']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $search_res_ids).') AND PrimaryCat = 1';
}
else {
$type_clauses['search']['include'] = '0';
$type_clauses['search']['except'] = '1';
}
$type_clauses['search']['having_filter'] = false;
}
if (in_array('related', $types) || in_array('related', $except_types)) {
$related_to = $event->getEventParam('related_to');
if (!$related_to) {
$related_prefix = $event->Prefix;
}
else {
$sql = 'SELECT Prefix
FROM '.TABLE_PREFIX.'ItemTypes
WHERE ItemName = '.$this->Conn->qstr($related_to);
$related_prefix = $this->Conn->GetOne($sql);
}
$rel_table = $this->Application->getUnitOption('rel', 'TableName');
$item_type = $this->Application->getUnitOption($event->Prefix, 'ItemType');
$p_item =& $this->Application->recallObject($related_prefix.'.current', null, Array('skip_autoload' => true));
$p_item->Load( $this->Application->GetVar($related_prefix.'_id') );
$p_resource_id = $p_item->GetDBField('ResourceId');
$sql = 'SELECT SourceId, TargetId FROM '.$rel_table.'
WHERE
(Enabled = 1)
AND (
(Type = 0 AND SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.')
OR
(Type = 1
AND (
(SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.')
OR
(TargetId = '.$p_resource_id.' AND SourceType = '.$item_type.')
)
)
)';
$related_ids_array = $this->Conn->Query($sql);
$related_ids = Array();
foreach ($related_ids_array as $key => $record) {
$related_ids[] = $record[ $record['SourceId'] == $p_resource_id ? 'TargetId' : 'SourceId' ];
}
if (count($related_ids) > 0) {
$type_clauses['related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_ids).') AND PrimaryCat = 1';
$type_clauses['related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_ids).') AND PrimaryCat = 1';
}
else {
$type_clauses['related']['include'] = '0';
$type_clauses['related']['except'] = '1';
}
$type_clauses['related']['having_filter'] = false;
}
if (in_array('favorites', $types) || in_array('favorites', $except_types)) {
$sql = 'SELECT ResourceId
FROM '.$this->Application->getUnitOption('fav', 'TableName').'
WHERE PortalUserId = '.$this->Application->RecallVar('user_id');
$favorite_ids = $this->Conn->GetCol($sql);
if ($favorite_ids) {
$type_clauses['favorites']['include'] = '%1$s.ResourceId IN ('.implode(',', $favorite_ids).') AND PrimaryCat = 1';
$type_clauses['favorites']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $favorite_ids).') AND PrimaryCat = 1';
}
else {
$type_clauses['favorites']['include'] = 0;
$type_clauses['favorites']['except'] = 1;
}
$type_clauses['favorites']['having_filter'] = false;
}
return $type_clauses;
}
/**
* Returns SQL clause, that will help to select only data from specified category & it's children
*
* @param int $category_id
* @return string
*/
function getCategoryLimitClause($category_id)
{
if (!$category_id) {
return false;
}
$sql = 'SELECT TreeLeft, TreeRight
FROM '.TABLE_PREFIX.'Category
WHERE CategoryId = '.$category_id;
$tree_indexes = $this->Conn->GetRow($sql);
return TABLE_PREFIX.'Category.TreeLeft BETWEEN '.$tree_indexes['TreeLeft'].' AND '.$tree_indexes['TreeRight'];
}
/**
* Apply filters to list
*
* @param kEvent $event
*/
function SetCustomQuery(&$event)
{
parent::SetCustomQuery($event);
$object =& $event->getObject();
// add category filter if needed
if ($event->Special != 'showall') {
if ($event->getEventParam('parent_cat_id') !== false) {
$parent_cat_id = $event->getEventParam('parent_cat_id');
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
if (!$parent_cat_id) {
$parent_cat_id = 0;
}
}
if ((string) $parent_cat_id != 'any') {
if ($event->getEventParam('recursive')) {
$filter_clause = $this->getCategoryLimitClause($parent_cat_id);
if ($filter_clause !== false) {
$object->addFilter('category_filter', $filter_clause);
}
$object->addFilter('primary_filter', 'PrimaryCat = 1');
}
else {
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.CategoryId = '.$parent_cat_id );
}
}
}
else {
$object->addFilter('primary_filter', 'PrimaryCat = 1');
}
// add permission filter
if ($this->Application->RecallVar('user_id') == -1) {
// for "root" CATEGORY.VIEW permission is checked for items lists too
$view_perm = 1;
}
else {
// for any real user itemlist view permission is checked instead of CATEGORY.VIEW
$count_helper =& $this->Application->recallObject('CountHelper');
/* @var $count_helper kCountHelper */
list ($view_perm, $view_filter) = $count_helper->GetPermissionClause($event->Prefix, 'perm');
$object->addFilter('perm_filter2', $view_filter);
}
$object->addFilter('perm_filter', 'perm.PermId = '.$view_perm);
$types = $event->getEventParam('types');
$this->applyItemStatusFilter($object, $types);
$except_types = $event->getEventParam('except');
$type_clauses = $this->getTypeClauses($event);
// convert prepared type clauses into list filters
$includes_or_filter =& $this->Application->makeClass('kMultipleFilter');
$includes_or_filter->setType(FLT_TYPE_OR);
$excepts_and_filter =& $this->Application->makeClass('kMultipleFilter');
$excepts_and_filter->setType(FLT_TYPE_AND);
$includes_or_filter_h =& $this->Application->makeClass('kMultipleFilter');
$includes_or_filter_h->setType(FLT_TYPE_OR);
$excepts_and_filter_h =& $this->Application->makeClass('kMultipleFilter');
$excepts_and_filter_h->setType(FLT_TYPE_AND);
if ($types) {
$types_array = explode(',', $types);
for ($i = 0; $i < sizeof($types_array); $i++) {
$type = trim($types_array[$i]);
if (isset($type_clauses[$type])) {
if ($type_clauses[$type]['having_filter']) {
$includes_or_filter_h->removeFilter('filter_'.$type);
$includes_or_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['include']);
}else {
$includes_or_filter->removeFilter('filter_'.$type);
$includes_or_filter->addFilter('filter_'.$type, $type_clauses[$type]['include']);
}
}
}
}
if ($except_types) {
$except_types_array = explode(',', $except_types);
for ($i = 0; $i < sizeof($except_types_array); $i++) {
$type = trim($except_types_array[$i]);
if (isset($type_clauses[$type])) {
if ($type_clauses[$type]['having_filter']) {
$excepts_and_filter_h->removeFilter('filter_'.$type);
$excepts_and_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['except']);
}else {
$excepts_and_filter->removeFilter('filter_'.$type);
$excepts_and_filter->addFilter('filter_'.$type, $type_clauses[$type]['except']);
}
}
}
}
/*if ( !$this->Application->IsAdmin() ) {
$object->addFilter('expire_filter', '%1$s.Expire IS NULL OR %1$s.Expire > UNIX_TIMESTAMP()');
}*/
/*$list_type = $event->getEventParam('ListType');
switch($list_type)
{
case 'favorites':
$fav_table = $this->Application->getUnitOption('fav','TableName');
$user_id =& $this->Application->RecallVar('user_id');
$sql = 'SELECT DISTINCT f.ResourceId
FROM '.$fav_table.' f
LEFT JOIN '.$object->TableName.' p ON p.ResourceId = f.ResourceId
WHERE f.PortalUserId = '.$user_id;
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('category_filter', TABLE_PREFIX.'CategoryItems.PrimaryCat = 1');
$object->addFilter('favorites_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
case 'search':
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = ' SELECT DISTINCT ResourceId
FROM '.$search_results_table.'
WHERE ItemType=11';
$ids = $this->Conn->GetCol($sql);
if(!$ids) $ids = Array(-1);
$object->addFilter('search_filter', '%1$s.`ResourceId` IN ('.implode(',',$ids).')');
break;
} */
$object->addFilter('includes_filter', $includes_or_filter);
$object->addFilter('excepts_filter', $excepts_and_filter);
$object->addFilter('includes_filter_h', $includes_or_filter_h, HAVING_FILTER);
$object->addFilter('excepts_filter_h', $excepts_and_filter_h, HAVING_FILTER);
}
/**
* Adds filter that filters out items with non-required statuses
*
* @param kDBList $object
* @param string $types
*/
function applyItemStatusFilter(&$object, $types)
{
// Link1 (before modifications) [Status = 1, OrgId = NULL], Link2 (after modifications) [Status = -2, OrgId = Link1_ID]
$pending_editing = $this->Application->getUnitOption($object->Prefix, 'UsePendingEditing');
if ( !$this->Application->IsAdmin() ) {
$types = explode(',', $types);
if (in_array('my_items', $types)) {
$allow_statuses = Array (STATUS_ACTIVE, STATUS_PENDING, STATUS_PENDING_EDITING);
$object->addFilter('status_filter', '%1$s.Status IN ('.implode(',', $allow_statuses).')');
if ($pending_editing) {
$user_id = $this->Application->RecallVar('user_id');
$this->applyPendingEditingFilter($object, $user_id);
}
}
else {
$object->addFilter('status_filter', '%1$s.Status = 1');
if ($pending_editing) {
// if category item uses pending editing abilities, then in no cases show pending copies on front
$object->addFilter('original_filter', '%1$s.OrgId = 0 OR %1$s.OrgId IS NULL');
}
}
}
else {
if ($pending_editing) {
$this->applyPendingEditingFilter($object);
}
}
}
/**
* Adds filter, that removes live items if they have pending editing copies
*
* @param kDBList $object
* @param int $user_id
*/
function applyPendingEditingFilter(&$object, $user_id = null)
{
$sql = 'SELECT OrgId
FROM '.$object->TableName.'
WHERE Status = '.STATUS_PENDING_EDITING.' AND OrgId IS NOT NULL';
if (isset($user_id)) {
$owner_field = $this->getOwnerField($object->Prefix);
$sql .= ' AND '.$owner_field.' = '.$user_id;
}
$pending_ids = $this->Conn->GetCol($sql);
if ($pending_ids) {
$object->addFilter('no_original_filter', '%1$s.'.$object->IDField.' NOT IN ('.implode(',', $pending_ids).')');
}
}
/**
* Adds calculates fields for item statuses
*
* @param kCatDBItem $object
* @param kEvent $event
*/
function prepareObject(&$object, &$event)
{
$this->prepareItemStatuses($event);
$object->addCalculatedField('CachedNavbar', 'l'.$this->Application->GetVar('m_lang').'_CachedNavbar');
if ($event->Special == 'export' || $event->Special == 'import')
{
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$export_helper->prepareExportColumns($event);
}
}
/**
* Creates calculated fields for all item statuses based on config settings
*
* @param kEvent $event
*/
function prepareItemStatuses(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return ;
}
// new items
$object->addCalculatedField('IsNew', ' IF(%1$s.NewItem = 2,
IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($property_map['NewDays']).
'*3600*24), 1, 0),
%1$s.NewItem
)');
// hot items (cache updated every hour)
$sql = 'SELECT Data
FROM '.TABLE_PREFIX.'Cache
WHERE (VarName = "'.$property_map['HotLimit'].'") AND (Cached >'.(adodb_mktime() - 3600).')';
$hot_limit = $this->Conn->GetOne($sql);
if ($hot_limit === false) {
$hot_limit = $this->CalculateHotLimit($event);
}
$object->addCalculatedField('IsHot', ' IF(%1$s.HotItem = 2,
IF(%1$s.'.$property_map['ClickField'].' >= '.$hot_limit.', 1, 0),
%1$s.HotItem
)');
// popular items
$object->addCalculatedField('IsPop', ' IF(%1$s.PopItem = 2,
IF(%1$s.CachedVotesQty >= '.
$this->Application->ConfigValue($property_map['MinPopVotes']).
' AND %1$s.CachedRating >= '.
$this->Application->ConfigValue($property_map['MinPopRating']).
', 1, 0),
%1$s.PopItem)');
}
function CalculateHotLimit(&$event)
{
$property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return;
}
$click_field = $property_map['ClickField'];
$last_hot = $this->Application->ConfigValue($property_map['MaxHotNumber']) - 1;
$sql = 'SELECT '.$click_field.' FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
ORDER BY '.$click_field.' DESC
LIMIT '.$last_hot.', 1';
$res = $this->Conn->GetCol($sql);
$hot_limit = (double)array_shift($res);
$this->Conn->Query('REPLACE INTO '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("'.$property_map['HotLimit'].'", "'.$hot_limit.'", '.adodb_mktime().')');
return $hot_limit;
return 0;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnBeforeItemUpdate(&$event)
{
$property_map = $this->Application->getUnitOption($event->Prefix, 'ItemPropertyMappings');
if (!$property_map) {
return;
}
$click_field = $property_map['ClickField'];
$object =& $event->getObject();
if( $this->Application->IsAdmin() && ($this->Application->GetVar($click_field.'_original') !== false) &&
floor($this->Application->GetVar($click_field.'_original')) != $object->GetDBField($click_field) )
{
$sql = 'SELECT MAX('.$click_field.') FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').'
WHERE FLOOR('.$click_field.') = '.$object->GetDBField($click_field);
$hits = ( $res = $this->Conn->GetOne($sql) ) ? $res + 0.000001 : $object->GetDBField($click_field);
$object->SetDBField($click_field, $hits);
}
}
/**
* Load price from temp table if product mode is temp table
*
* @param kEvent $event
*/
function OnAfterItemLoad(&$event)
{
$special = substr($event->Special, -6);
$object =& $event->getObject();
/* @var $object kCatDBItem */
if ($special == 'import' || $special == 'export') {
$image_data = $object->getPrimaryImageData();
if ($image_data) {
$thumbnail_image = $image_data[$image_data['LocalThumb'] ? 'ThumbPath' : 'ThumbUrl'];
if ($image_data['SameImages']) {
$full_image = '';
}
else {
$full_image = $image_data[$image_data['LocalImage'] ? 'LocalPath' : 'Url'];
}
$object->SetDBField('ThumbnailImage', $thumbnail_image);
$object->SetDBField('FullImage', $full_image);
$object->SetDBField('ImageAlt', $image_data['AltName']);
}
}
// substituiting pending status value for pending editing
if ($object->HasField('OrgId') && $object->GetDBField('OrgId') > 0 && $object->GetDBField('Status') == -2) {
$options = $object->Fields['Status']['options'];
foreach ($options as $key => $val) {
if ($key == 2) $key = -2;
$new_options[$key] = $val;
}
$object->Fields['Status']['options'] = $new_options;
}
// linking existing images for item with virtual fields
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
$image_helper->LoadItemImages($object);
+ // linking existing files for item with virtual fields
+ $file_helper =& $this->Application->recallObject('FileHelper');
+ /* @var $file_helper FileHelper */
+
+ $file_helper->LoadItemFiles($object);
+
// set item's additional categories to virtual field (used in editing)
$item_categories = $this->getItemCategories($object->GetDBField('ResourceId'));
$object->SetDBField('MoreCategories', $item_categories ? '|'.implode('|', $item_categories).'|' : '');
}
function OnAfterItemUpdate(&$event)
{
$this->CalculateHotLimit($event);
if ( substr($event->Special, -6) == 'import') {
$this->setCustomExportColumns($event);
}
if (!$this->Application->IsAdmin()) {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
$object =& $event->getObject();
/* @var $object kDBItem */
// process image upload in virtual fields
$image_helper->SaveItemImages($object);
+ $file_helper =& $this->Application->recallObject('FileHelper');
+ /* @var $file_helper FileHelper */
+
+ // process file upload in virtual fields
+ $file_helper->SaveItemFiles($object);
+
if ($event->Special != '-item') {
// don't touch categories during cloning
$this->processAdditionalCategories($object, 'update');
}
}
}
/**
* sets values for import process
*
* @param kEvent $event
*/
function OnAfterItemCreate(&$event)
{
if ( substr($event->Special, -6) == 'import') {
$this->setCustomExportColumns($event);
}
if (!$this->Application->IsAdmin()) {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
$object =& $event->getObject();
/* @var $object kDBItem */
// process image upload in virtual fields
$image_helper->SaveItemImages($object);
+ $file_helper =& $this->Application->recallObject('FileHelper');
+ /* @var $file_helper FileHelper */
+
+ // process file upload in virtual fields
+ $file_helper->SaveItemFiles($object);
+
if ($event->Special != '-item') {
// don't touch categories during cloning
$this->processAdditionalCategories($object, 'create');
}
}
}
/**
* Make record to search log
*
* @param string $keywords
* @param int $search_type 0 - simple search, 1 - advanced search
*/
function saveToSearchLog($keywords, $search_type = 0)
{
$sql = 'UPDATE '.TABLE_PREFIX.'SearchLog
SET Indices = Indices + 1
WHERE Keyword = '.$this->Conn->qstr($keywords).' AND SearchType = '.$search_type; // 0 - simple search, 1 - advanced search
$this->Conn->Query($sql);
if ($this->Conn->getAffectedRows() == 0) {
$fields_hash = Array('Keyword' => $keywords, 'Indices' => 1, 'SearchType' => $search_type);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'SearchLog');
}
}
/**
* Makes simple search for products
* based on keywords string
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnSimpleSearch(&$event)
{
if($this->Application->GetVar('INPORTAL_ON') && !($this->Application->GetVar('Action') == 'm_simple_search'))
{
return;
}
$event->redirect = false;
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$keywords = unhtmlentities( trim($this->Application->GetVar('keywords')) );
$query_object =& $this->Application->recallObject('HTTPQuery');
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if(!isset($query_object->Get['keywords']) &&
!isset($query_object->Post['keywords']) &&
$this->Conn->Query($sql))
{
return; // used when navigating by pages or changing sorting in search results
}
if(!$keywords || strlen($keywords) < $this->Application->ConfigValue('Search_MinKeyword_Length'))
{
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$this->Application->SetVar('keywords_too_short', 1);
return; // if no or too short keyword entered, doing nothing
}
$this->Application->StoreVar('keywords', $keywords);
if (!$this->Application->GetVar('INPORTAL_ON')) {
// don't save search log, because in-portal already saved it
$this->saveToSearchLog($keywords, 0); // 0 - simple search, 1 - advanced search
}
$keywords = strtr($keywords, Array('%' => '\\%', '_' => '\\_'));
$event->setPseudoClass('_List');
$object =& $event->getObject();
$this->Application->SetVar($event->getPrefixSpecial().'_Page', 1);
$lang = $this->Application->GetVar('m_lang');
$items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$module_name = $this->Application->findModule('Var', $event->Prefix, 'Name');
$sql = ' SELECT * FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE ModuleName="'.$module_name.'"
AND SimpleSearch=1';
$search_config = $this->Conn->Query($sql, 'FieldName');
$field_list = array_keys($search_config);
$join_clauses = Array();
// field processing
$weight_sum = 0;
$alias_counter = 0;
$custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
if ($custom_fields) {
$custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
$join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$items_table.'.ResourceId = custom_data.ResourceId';
}
// what field in search config becomes what field in sql (key - new field, value - old field (from searchconfig table))
$search_config_map = Array();
foreach ($field_list as $key => $field) {
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$search_config[$field]['TableName'];
$weight_sum += $search_config[$field]['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if (getArrayValue($options, 'formatter') == 'kMultiLanguage') {
$field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_'.$field;
$field_list[$key] = 'l'.$lang.'_'.$field;
if(!isset($search_config[$field]['ForeignField']))
{
$field_list[$key.'_primary'] = $local_table.'.'.$field_list[$key.'_primary'];
$search_config_map[ $field_list[$key.'_primary'] ] = $field;
}
}
// processing fields from other tables
if($foreign_field = $search_config[$field]['ForeignField'])
{
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
unset($field_list[$key]);
continue; // ignoring having type clauses in simple search
/*$user_groups = $this->Application->RecallVar('UserGroups');
$having_list[$key] = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$join_clauses[] = $join_clause;*/
}
else
{
$multi_lingual = false;
if ($exploded[0] == 'MULTI')
{
$multi_lingual = true;
$foreign_field = $exploded[1];
}
$exploded = explode('.', $foreign_field); // format: table.field_name
$foreign_table = TABLE_PREFIX.$exploded[0];
$alias_counter++;
$alias = 't'.$alias_counter;
if ($multi_lingual) {
$field_list[$key] = $alias.'.'.'l'.$lang.'_'.$exploded[1];
$field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_'.$field;
$search_config_map[ $field_list[$key] ] = $field;
$search_config_map[ $field_list[$key.'_primary'] ] = $field;
}
else {
$field_list[$key] = $alias.'.'.$exploded[1];
$search_config_map[ $field_list[$key] ] = $field;
}
$join_clause = str_replace('{ForeignTable}', $alias, $search_config[$field]['JoinClause']);
$join_clause = str_replace('{LocalTable}', $items_table, $join_clause);
$join_clauses[] = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else {
// processing fields from local table
if ($search_config[$field]['CustomFieldId']) {
$local_table = 'custom_data';
// search by custom field value on current language
$custom_field_id = array_search($field_list[$key], $custom_fields);
$field_list[$key] = 'l'.$lang.'_cust_'.$custom_field_id;
// search by custom field value on primary language
$field_list[$key.'_primary'] = 'l'.$this->Application->GetDefaultLanguageId().'_cust_'.$custom_field_id;
$search_config_map[ $field_list[$key.'_primary'] ] = $field;
}
$field_list[$key] = $local_table.'.'.$field_list[$key];
$search_config_map[ $field_list[$key] ] = $field;
}
}
// keyword string processing
$search_helper =& $this->Application->recallObject('SearchHelper');
$where_clause = $search_helper->buildWhereClause($keywords, $field_list);
$search_scope = $this->Application->GetVar('search_scope');
if ($search_scope == 'category') {
$category_id = $this->Application->GetVar('m_cat_id');
$category_filter = $this->getCategoryLimitClause($category_id);
if ($category_filter !== false) {
$join_clauses[] = ' LEFT JOIN '.TABLE_PREFIX.'CategoryItems ON '.TABLE_PREFIX.'CategoryItems.ItemResourceId = '.$items_table.'.ResourceId';
$join_clauses[] = ' LEFT JOIN '.TABLE_PREFIX.'Category ON '.TABLE_PREFIX.'Category.CategoryId = '.TABLE_PREFIX.'CategoryItems.CategoryId';
$where_clause = '('.$this->getCategoryLimitClause($category_id).') AND '.$where_clause;
}
}
$where_clause = $where_clause.' AND '.$items_table.'.Status=1';
if($this->Application->GetVar('Action') == 'm_simple_subsearch') // subsearch, In-portal
{
if( $event->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$items_table.'.ResourceId IN ('.implode(',', $event->specificParams['ResultIds']).')';
}
}
if( $event->MasterEvent && $event->MasterEvent->Name == 'OnListBuild' ) // subsearch, k4
{
if( $event->MasterEvent->getEventParam('ResultIds') )
{
$where_clause .= ' AND '.$items_table.'.ResourceId IN ('.implode(',', $event->MasterEvent->getEventParam('ResultIds')).')';
}
}
// making relevance clause
$positive_words = $search_helper->getPositiveKeywords($keywords);
$this->Application->StoreVar('highlight_keywords', serialize($positive_words));
$revelance_parts = Array();
reset($search_config);
foreach ($field_list as $field) {
$config_elem = $search_config[ $search_config_map[$field] ];
$weight = $config_elem['Priority'];
$revelance_parts[] = 'IF('.$field.' LIKE "%'.implode(' ', $positive_words).'%", '.$weight_sum.', 0)';
foreach ($positive_words as $keyword) {
$revelance_parts[] = 'IF('.$field.' LIKE "%'.$keyword.'%", '.$weight.', 0)';
}
}
$conf_postfix = $this->Application->getUnitOption($event->Prefix, 'SearchConfigPostfix');
$rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_'.$conf_postfix) / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_Pop_'.$conf_postfix) / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_Rating_'.$conf_postfix) / 100;
$relevance_clause = '('.implode(' + ', $revelance_parts).') / '.$weight_sum.' * '.$rel_keywords;
if ($rel_pop && isset($object->Fields['Hits'])) {
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
}
if ($rel_rating && isset($object->Fields['CachedRating'])) {
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
}
// building final search query
if (!$this->Application->GetVar('do_not_drop_search_table') && !$this->Application->GetVar('INPORTAL_ON')) {
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table); // erase old search table if clean k4 event
$this->Application->SetVar('do_not_drop_search_table', true);
}
$search_table_exists = $this->Conn->Query('SHOW TABLES LIKE "'.$search_table.'"');
if ($search_table_exists) {
$select_intro = 'INSERT INTO '.$search_table.' (Relevance, ItemId, ResourceId, ItemType, EdPick) ';
}
else {
$select_intro = 'CREATE TABLE '.$search_table.' AS ';
}
$edpick_clause = $this->Application->getUnitOption($event->Prefix.'.EditorsPick', 'Fields') ? $items_table.'.EditorsPick' : '0';
$sql = $select_intro.' SELECT '.$relevance_clause.' AS Relevance,
'.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField').' AS ItemId,
'.$items_table.'.ResourceId,
'.$this->Application->getUnitOption($event->Prefix, 'ItemType').' AS ItemType,
'.$edpick_clause.' AS EdPick
FROM '.$object->TableName.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$items_table.'.'.$this->Application->getUnitOption($event->Prefix, 'IDField');
$res = $this->Conn->Query($sql);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSubSearch(&$event)
{
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = 'SHOW TABLES LIKE "'.$search_table.'"';
if($this->Conn->Query($sql))
{
$sql = 'SELECT DISTINCT ResourceId FROM '.$search_table;
$ids = $this->Conn->GetCol($sql);
}
$event->setEventParam('ResultIds', $ids);
$event->CallSubEvent('OnSimpleSearch');
}
/**
* Enter description here...
*
* @param kEvent $event
* @todo Change all hardcoded Products table & In-Commerce module usage to dynamic usage from item config !!!
*/
function OnAdvancedSearch(&$event)
{
$query_object =& $this->Application->recallObject('HTTPQuery');
if(!isset($query_object->Post['andor']))
{
return; // used when navigating by pages or changing sorting in search results
}
$this->Application->RemoveVar('keywords');
$this->Application->RemoveVar('Search_Keywords');
$module_name = $this->Application->findModule('Var', $event->Prefix, 'Name');
$sql = 'SELECT *
FROM '.$this->Application->getUnitOption('confs', 'TableName').'
WHERE (ModuleName = '.$this->Conn->qstr($module_name).') AND (AdvancedSearch = 1)';
$search_config = $this->Conn->Query($sql);
$lang = $this->Application->GetVar('m_lang');
$object =& $event->getObject();
$object->SetPage(1);
$items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
$search_keywords = $this->Application->GetVar('value'); // will not be changed
$keywords = $this->Application->GetVar('value'); // will be changed down there
$verbs = $this->Application->GetVar('verb');
$glues = $this->Application->GetVar('andor');
$and_conditions = Array();
$or_conditions = Array();
$and_having_conditions = Array();
$or_having_conditions = Array();
$join_clauses = Array();
$highlight_keywords = Array();
$relevance_parts = Array();
$alias_counter = 0;
$custom_fields = $this->Application->getUnitOption($event->Prefix, 'CustomFields');
if ($custom_fields) {
$custom_table = $this->Application->getUnitOption($event->Prefix.'-cdata', 'TableName');
$join_clauses[] = ' LEFT JOIN '.$custom_table.' custom_data ON '.$items_table.'.ResourceId = custom_data.ResourceId';
}
$search_log = '';
$weight_sum = 0;
// processing fields and preparing conditions
foreach ($search_config as $record) {
$field = $record['FieldName'];
$join_clause = '';
$condition_mode = 'WHERE';
// field processing
$options = $object->getFieldOptions($field);
$local_table = TABLE_PREFIX.$record['TableName'];
$weight_sum += $record['Priority']; // counting weight sum; used when making relevance clause
// processing multilingual fields
if (getArrayValue($options, 'formatter') == 'kMultiLanguage') {
$field_name = 'l'.$lang.'_'.$field;
}
else {
$field_name = $field;
}
// processing fields from other tables
if ($foreign_field = $record['ForeignField']) {
$exploded = explode(':', $foreign_field, 2);
if($exploded[0] == 'CALC')
{
$user_groups = $this->Application->RecallVar('UserGroups');
$field_name = str_replace('{PREFIX}', TABLE_PREFIX, $exploded[1]);
$join_clause = str_replace('{PREFIX}', TABLE_PREFIX, $record['JoinClause']);
$join_clause = str_replace('{USER_GROUPS}', $user_groups, $join_clause);
$join_clause = ' LEFT JOIN '.$join_clause;
$condition_mode = 'HAVING';
}
else {
$exploded = explode('.', $foreign_field);
$foreign_table = TABLE_PREFIX.$exploded[0];
if($record['CustomFieldId']) {
$exploded[1] = 'l'.$lang.'_'.$exploded[1];
}
$alias_counter++;
$alias = 't'.$alias_counter;
$field_name = $alias.'.'.$exploded[1];
$join_clause = str_replace('{ForeignTable}', $alias, $record['JoinClause']);
$join_clause = str_replace('{LocalTable}', $items_table, $join_clause);
if($record['CustomFieldId'])
{
$join_clause .= ' AND '.$alias.'.CustomFieldId='.$record['CustomFieldId'];
}
$join_clause = ' LEFT JOIN '.$foreign_table.' '.$alias.'
ON '.$join_clause;
}
}
else
{
// processing fields from local table
if ($record['CustomFieldId']) {
$local_table = 'custom_data';
$field_name = 'l'.$lang.'_cust_'.array_search($field_name, $custom_fields);
}
$field_name = $local_table.'.'.$field_name;
}
$condition = $this->getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, $highlight_keywords);
if ($record['CustomFieldId'] && strlen($condition)) {
// search in primary value of custom field + value in current language
$field_name = $local_table.'.'.'l'.$this->Application->GetDefaultLanguageId().'_cust_'.array_search($field, $custom_fields);
$primary_condition = $this->getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, $highlight_keywords);
$condition = '('.$condition.' OR '.$primary_condition.')';
}
if ($condition) {
if ($join_clause) {
$join_clauses[] = $join_clause;
}
$relevance_parts[] = 'IF('.$condition.', '.$record['Priority'].', 0)';
if ($glues[$field] == 1) { // and
if ($condition_mode == 'WHERE') {
$and_conditions[] = $condition;
}
else {
$and_having_conditions[] = $condition;
}
}
else { // or
if ($condition_mode == 'WHERE') {
$or_conditions[] = $condition;
}
else {
$or_having_conditions[] = $condition;
}
}
// create search log record
$search_log_data = Array('search_config' => $record, 'verb' => getArrayValue($verbs, $field), 'value' => ($record['FieldType'] == 'range') ? $search_keywords[$field.'_from'].'|'.$search_keywords[$field.'_to'] : $search_keywords[$field]);
$search_log[] = $this->Application->Phrase('la_Field').' "'.$this->getHuman('Field', $search_log_data).'" '.$this->getHuman('Verb', $search_log_data).' '.$this->Application->Phrase('la_Value').' '.$this->getHuman('Value', $search_log_data).' '.$this->Application->Phrase($glues[$field] == 1 ? 'lu_And' : 'lu_Or');
}
}
if ($search_log) {
$search_log = implode('<br />', $search_log);
$search_log = preg_replace('/(.*) '.preg_quote($this->Application->Phrase('lu_and'), '/').'|'.preg_quote($this->Application->Phrase('lu_or'), '/').'$/is', '\\1', $search_log);
$this->saveToSearchLog($search_log, 1); // advanced search
}
$this->Application->StoreVar('highlight_keywords', serialize($highlight_keywords));
// making relevance clause
if($relevance_parts)
{
$conf_postfix = $this->Application->getUnitOption($event->Prefix, 'SearchConfigPostfix');
$rel_keywords = $this->Application->ConfigValue('SearchRel_Keyword_'.$conf_postfix) / 100;
$rel_pop = $this->Application->ConfigValue('SearchRel_Pop_'.$conf_postfix) / 100;
$rel_rating = $this->Application->ConfigValue('SearchRel_Rating_'.$conf_postfix) / 100;
$relevance_clause = '('.implode(' + ', $relevance_parts).') / '.$weight_sum.' * '.$rel_keywords;
$relevance_clause .= ' + (Hits + 1) / (MAX(Hits) + 1) * '.$rel_pop;
$relevance_clause .= ' + (CachedRating + 1) / (MAX(CachedRating) + 1) * '.$rel_rating;
}
else
{
$relevance_clause = '0';
}
// building having clause
if($or_having_conditions)
{
$and_having_conditions[] = '('.implode(' OR ', $or_having_conditions).')';
}
$having_clause = implode(' AND ', $and_having_conditions);
$having_clause = $having_clause ? ' HAVING '.$having_clause : '';
// building where clause
if($or_conditions)
{
$and_conditions[] = '('.implode(' OR ', $or_conditions).')';
}
// $and_conditions[] = $items_table.'.Status = 1';
$where_clause = implode(' AND ', $and_conditions);
if(!$where_clause)
{
if($having_clause)
{
$where_clause = '1';
}
else
{
$where_clause = '0';
$this->Application->SetVar('adv_search_error', 1);
}
}
$where_clause .= ' AND '.$items_table.'.Status = 1';
// building final search query
$search_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$this->Conn->Query('DROP TABLE IF EXISTS '.$search_table);
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$pick_field = isset($fields['EditorsPick']) ? $items_table.'.EditorsPick' : '0';
$sql = ' CREATE TABLE '.$search_table.'
SELECT '.$relevance_clause.' AS Relevance,
'.$items_table.'.'.$id_field.' AS ItemId,
'.$items_table.'.ResourceId AS ResourceId,
11 AS ItemType,
'.$pick_field.' AS EdPick
FROM '.$items_table.'
'.implode(' ', $join_clauses).'
WHERE '.$where_clause.'
GROUP BY '.$items_table.'.'.$id_field.
$having_clause;
$res = $this->Conn->Query($sql);
}
function getAdvancedSearchCondition($field_name, $record, $keywords, $verbs, &$highlight_keywords)
{
$field = $record['FieldName'];
$condition_patterns = Array (
'any' => '%s LIKE %s',
'contains' => '%s LIKE %s',
'notcontains' => '(NOT (%1$s LIKE %2$s) OR %1$s IS NULL)',
'is' => '%s = %s',
'isnot' => '(%1$s != %2$s OR %1$s IS NULL)'
);
$condition = '';
switch ($record['FieldType']) {
case 'select':
$keywords[$field] = unhtmlentities( $keywords[$field] );
if ($keywords[$field]) {
$condition = sprintf($condition_patterns['is'], $field_name, $this->Conn->qstr( $keywords[$field] ));
}
break;
case 'multiselect':
$keywords[$field] = unhtmlentities( $keywords[$field] );
if ($keywords[$field]) {
$condition = Array ();
$values = explode('|', substr($keywords[$field], 1, -1));
foreach ($values as $selected_value) {
$condition[] = sprintf($condition_patterns['contains'], $field_name, $this->Conn->qstr('%|'.$selected_value.'|%'));
}
$condition = '('.implode(' OR ', $condition).')';
}
break;
case 'text':
$keywords[$field] = unhtmlentities( $keywords[$field] );
if (strlen($keywords[$field]) >= $this->Application->ConfigValue('Search_MinKeyword_Length')) {
$highlight_keywords[] = $keywords[$field];
if (in_array($verbs[$field], Array('any', 'contains', 'notcontains'))) {
$keywords[$field] = '%'.strtr($keywords[$field], Array('%' => '\\%', '_' => '\\_')).'%';
}
$condition = sprintf($condition_patterns[$verbs[$field]], $field_name, $this->Conn->qstr( $keywords[$field] ));
}
break;
case 'boolean':
if ($keywords[$field] != -1) {
$property_mappings = $this->Application->getUnitOption($this->Prefix, 'ItemPropertyMappings');
$items_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
switch ($field) {
case 'HotItem':
$hot_limit_var = getArrayValue($property_mappings, 'HotLimit');
if ($hot_limit_var) {
$sql = 'SELECT Data
FROM '.TABLE_PREFIX.'Cache
WHERE VarName = "'.$hot_limit_var.'"';
$hot_limit = (int)$this->Conn->GetOne($sql);
$condition = 'IF('.$items_table.'.HotItem = 2,
IF('.$items_table.'.Hits >= '.
$hot_limit.
', 1, 0), '.$items_table.'.HotItem) = '.$keywords[$field];
}
break;
case 'PopItem':
$votes2pop_var = getArrayValue($property_mappings, 'VotesToPop');
$rating2pop_var = getArrayValue($property_mappings, 'RatingToPop');
if ($votes2pop_var && $rating2pop_var) {
$condition = 'IF('.$items_table.'.PopItem = 2, IF('.$items_table.'.CachedVotesQty >= '.
$this->Application->ConfigValue($votes2pop_var).
' AND '.$items_table.'.CachedRating >= '.
$this->Application->ConfigValue($rating2pop_var).
', 1, 0), '.$items_table.'.PopItem) = '.$keywords[$field];
}
break;
case 'NewItem':
$new_days_var = getArrayValue($property_mappings, 'NewDays');
if ($new_days_var) {
$condition = 'IF('.$items_table.'.NewItem = 2,
IF('.$items_table.'.CreatedOn >= (UNIX_TIMESTAMP() - '.
$this->Application->ConfigValue($new_days_var).
'*3600*24), 1, 0), '.$items_table.'.NewItem) = '.$keywords[$field];
}
break;
case 'EditorsPick':
$condition = $items_table.'.EditorsPick = '.$keywords[$field];
break;
}
}
break;
case 'range':
$range_conditions = Array();
if ($keywords[$field.'_from'] && !preg_match("/[^0-9]/i", $keywords[$field.'_from'])) {
$range_conditions[] = $field_name.' >= '.$keywords[$field.'_from'];
}
if ($keywords[$field.'_to'] && !preg_match("/[^0-9]/i", $keywords[$field.'_to'])) {
$range_conditions[] = $field_name.' <= '.$keywords[$field.'_to'];
}
if ($range_conditions) {
$condition = implode(' AND ', $range_conditions);
}
break;
case 'date':
if ($keywords[$field]) {
if (in_array($keywords[$field], Array('today', 'yesterday'))) {
$current_time = getdate();
$day_begin = adodb_mktime(0, 0, 0, $current_time['mon'], $current_time['mday'], $current_time['year']);
$time_mapping = Array('today' => $day_begin, 'yesterday' => ($day_begin - 86400));
$min_time = $time_mapping[$keywords[$field]];
}
else {
$time_mapping = Array (
'last_week' => 604800, 'last_month' => 2628000, 'last_3_months' => 7884000,
'last_6_months' => 15768000, 'last_year' => 31536000,
);
$min_time = adodb_mktime() - $time_mapping[$keywords[$field]];
}
$condition = $field_name.' > '.$min_time;
}
break;
}
return $condition;
}
function getHuman($type, $search_data)
{
$type = ucfirst(strtolower($type));
extract($search_data);
switch ($type) {
case 'Field':
return $this->Application->Phrase($search_config['DisplayName']);
break;
case 'Verb':
return $verb ? $this->Application->Phrase('lu_advsearch_'.$verb) : '';
break;
case 'Value':
switch ($search_config['FieldType']) {
case 'date':
$values = Array(0 => 'lu_comm_Any', 'today' => 'lu_comm_Today',
'yesterday' => 'lu_comm_Yesterday', 'last_week' => 'lu_comm_LastWeek',
'last_month' => 'lu_comm_LastMonth', 'last_3_months' => 'lu_comm_Last3Months',
'last_6_months' => 'lu_comm_Last6Months', 'last_year' => 'lu_comm_LastYear');
$ret = $this->Application->Phrase($values[$value]);
break;
case 'range':
$value = explode('|', $value);
return $this->Application->Phrase('lu_comm_From').' "'.$value[0].'" '.$this->Application->Phrase('lu_comm_To').' "'.$value[1].'"';
break;
case 'boolean':
$values = Array(1 => 'lu_comm_Yes', 0 => 'lu_comm_No', -1 => 'lu_comm_Both');
$ret = $this->Application->Phrase($values[$value]);
break;
default:
$ret = $value;
break;
}
return '"'.$ret.'"';
break;
}
}
/**
* Set's correct page for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetPagination(&$event)
{
// get PerPage (forced -> session -> config -> 10)
$per_page = $this->getPerPage($event);
$object =& $event->getObject();
$object->SetPerPage($per_page);
$this->Application->StoreVarDefault($event->getPrefixSpecial().'_Page', 1);
$page = $this->Application->GetVar($event->getPrefixSpecial().'_Page');
if (!$page)
{
$page = $this->Application->GetVar($event->getPrefixSpecial(true).'_Page');
}
if (!$page)
{
if( $this->Application->RewriteURLs() )
{
$page = $this->Application->GetVar($event->Prefix.'_Page');
if (!$page)
{
$page = $this->Application->RecallVar($event->Prefix.'_Page');
}
if($page) $this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
else
{
$page = $this->Application->RecallVar($event->getPrefixSpecial().'_Page');
}
}
else {
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', $page);
}
if( !$event->getEventParam('skip_counting') )
{
$pages = $object->GetTotalPages();
if($page > $pages)
{
$this->Application->StoreVar($event->getPrefixSpecial().'_Page', 1);
$page = 1;
}
}
/*$cur_per_page = $per_page;
$per_page = $event->getEventParam('per_page');
if ($per_page == 'list_next') {
$cur_page = $page;
$object =& $this->Application->recallObject($event->Prefix);
$object->SetPerPage(1);
$cur_item_index = $object->CurrentIndex;
$page = ($cur_page-1) * $cur_per_page + $cur_item_index + 1;
$object->SetPerPage(1);
}*/
$object->SetPage($page);
}
/* === RELATED TO IMPORT/EXPORT: BEGIN === */
/**
* Shows export dialog
*
* @param kEvent $event
*/
function OnExport(&$event)
{
// use old fasion (in-portal) grid
$selector_name = $this->Application->getUnitOption($event->Prefix, 'CatalogSelectorName');
if ($selector_name) {
$selected_ids = $this->Application->GetVar($selector_name);
}
else {
$selected_ids = $this->StoreSelectedIDs($event);
if (implode(',', $selected_ids) == '') {
// K4 fix when no ids found bad selected ids array is formed
$selected_ids = false;
}
}
$selected_cats_ids = $this->Application->GetVar('export_categories');
$this->Application->StoreVar($event->Prefix.'_export_ids', $selected_ids ? implode(',', $selected_ids) : '' );
$this->Application->StoreVar($event->Prefix.'_export_cats_ids', $selected_cats_ids);
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$event->redirect = $export_helper->getModuleFolder($event).'/export';
$redirect_params = Array( 'm_opener' => 'd',
$this->Prefix.'.export_event' => 'OnNew',
'pass' => 'all,'.$this->Prefix.'.export');
$event->setRedirectParams($redirect_params);
}
/**
* Performs each export step & displays progress percent
*
* @param kEvent $event
*/
function OnExportProgress(&$event)
{
$export_object =& $this->Application->recallObject('CatItemExportHelper');
/* @var $export_object kCatDBItemExportHelper */
$event = new kEvent($event->getPrefixSpecial().':OnDummy');
$action_method = 'perform'.ucfirst($event->Special);
$field_values = $export_object->$action_method($event);
// finish code is done from JS now
if ($field_values['start_from'] == $field_values['total_records']) {
if ($event->Special == 'import') {
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
$this->Application->Redirect('in-portal/categories/cache_updater', Array('m_opener' => 'r', 'pass' => 'm', 'continue' => 1, 'no_amp' => 1));
}
elseif ($event->Special == 'export') {
$template = $this->Application->getUnitOption($event->Prefix, 'ModuleFolder').'/'.$event->Special.'_finish';
$this->Application->Redirect($template, Array('pass' => 'all'));
}
}
$export_options = $export_object->loadOptions($event);
echo $export_options['start_from'] * 100 / $export_options['total_records'];
$event->status = erSTOP;
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
*/
function getCustomExportColumns(&$event)
{
return Array( '__VIRTUAL__ThumbnailImage' => 'ThumbnailImage',
'__VIRTUAL__FullImage' => 'FullImage',
'__VIRTUAL__ImageAlt' => 'ImageAlt');
}
/**
* Sets non standart virtual fields (e.g. to other tables)
*
* @param kEvent $event
*/
function setCustomExportColumns(&$event)
{
$this->restorePrimaryImage($event);
}
/**
* Create/Update primary image record in info found in imported data
*
* @param kEvent $event
*/
function restorePrimaryImage(&$event)
{
$object =& $event->getObject();
$has_image_info = $object->GetDBField('ImageAlt') && ($object->GetDBField('ThumbnailImage') || $object->GetDBField('FullImage'));
if (!$has_image_info) {
return false;
}
$image_data = $object->getPrimaryImageData();
$image =& $this->Application->recallObject('img', null, Array('skip_autoload' => true));
if ($image_data) {
$image->Load($image_data['ImageId']);
}
else {
$image->Clear();
$image->SetDBField('Name', 'main');
$image->SetDBField('DefaultImg', 1);
$image->SetDBField('ResourceId', $object->GetDBField('ResourceId'));
}
$image->SetDBField('AltName', $object->GetDBField('ImageAlt'));
if ($object->GetDBField('ThumbnailImage')) {
$thumbnail_field = $this->isURL( $object->GetDBField('ThumbnailImage') ) ? 'ThumbUrl' : 'ThumbPath';
$image->SetDBField($thumbnail_field, $object->GetDBField('ThumbnailImage') );
$image->SetDBField('LocalThumb', $thumbnail_field == 'ThumbPath' ? 1 : 0);
}
if (!$object->GetDBField('FullImage')) {
$image->SetDBField('SameImages', 1);
}
else {
$image->SetDBField('SameImages', 0);
$full_field = $this->isURL( $object->GetDBField('FullImage') ) ? 'Url' : 'LocalPath';
$image->SetDBField($full_field, $object->GetDBField('FullImage') );
$image->SetDBField('LocalImage', $full_field == 'LocalPath' ? 1 : 0);
}
if ($image->isLoaded()) {
$image->Update();
}
else {
$image->Create();
}
}
function isURL($path)
{
return preg_match('#(http|https)://(.*)#', $path);
}
/**
* Prepares item for import/export operations
*
* @param kEvent $event
*/
function OnNew(&$event)
{
parent::OnNew($event);
if ($event->Special == 'import' || $event->Special == 'export') {
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
$export_helper->setRequiredFields($event);
$this->Application->StoreVar('ImportCategory', 0);
}
}
/**
* Process items selected in item_selector
*
* @param kEvent $event
*/
function OnProcessSelected(&$event)
{
$selected_ids = $this->Application->GetVar('selected_ids');
$dst_field = $this->Application->RecallVar('dst_field');
if ($dst_field == 'ItemCategory') {
// Item Edit -> Categories Tab -> New Categories
$object =& $event->getObject();
$category_ids = explode(',', $selected_ids['c']);
foreach ($category_ids as $category_id) {
$object->assignToCategory($category_id);
}
}
if ($dst_field == 'ImportCategory') {
// Tools -> Import -> Item Import -> Select Import Category
$this->Application->StoreVar('ImportCategory', $selected_ids['c']);
// $this->Application->StoreVar($event->getPrefixSpecial().'_ForceNotValid', 1); // not to loose import/export values on form refresh
$this->Application->SetVar($event->getPrefixSpecial().'_id', 0);
$this->Application->SetVar($event->getPrefixSpecial().'_event', 'OnExportBegin');
$passed = $this->Application->GetVar('passed');
$this->Application->SetVar('passed', $passed.','.$event->getPrefixSpecial());
$event->setEventParam('pass_events', true);
}
$this->finalizePopup($event);
}
/**
* Saves Import/Export settings to session
*
* @param kEvent $event
*/
function OnSaveSettings(&$event)
{
$event->redirect = false;
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
list($id, $field_values) = each($items_info);
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$field_values['ImportFilename'] = $object->GetDBField('ImportFilename'); //if upload formatter has renamed the file during moving !!!
$field_values['ImportSource'] = 2;
$field_values['ImportLocalFilename'] = $object->GetDBField('ImportFilename');
$items_info[$id] = $field_values;
$this->Application->StoreVar($event->getPrefixSpecial().'_ItemsInfo', serialize($items_info));
}
}
function OnCancelAction(&$event)
{
$event->redirect_params = Array('pass' => 'all,'.$event->GetPrefixSpecial());
$event->redirect = $this->Application->GetVar('cancel_template');
}
/* === RELATED TO IMPORT/EXPORT: END === */
/**
* Stores item's owner login into separate field together with id
*
* @param kEvent $event
* @param string $id_field
* @param string $cached_field
*/
function cacheItemOwner(&$event, $id_field, $cached_field)
{
$object =& $event->getObject();
$user_id = $object->GetDBField($id_field);
$options = $object->GetFieldOptions($id_field);
if (isset($options['options'][$user_id])) {
$object->SetDBField($cached_field, $options['options'][$user_id]);
}
else {
$id_field = $this->Application->getUnitOption('u', 'IDField');
$table_name = $this->Application->getUnitOption('u', 'TableName');
$sql = 'SELECT Login
FROM '.$table_name.'
WHERE '.$id_field.' = '.$user_id;
$object->SetDBField($cached_field, $this->Conn->GetOne($sql));
}
}
/**
* Saves item beeing edited into temp table
*
* @param kEvent $event
*/
function OnPreSave(&$event)
{
parent::OnPreSave($event);
$use_pending_editing = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($event->status == erSUCCESS && $use_pending_editing) {
// decision: clone or not clone
$object =& $event->getObject();
if ($object->GetID() == 0 || $object->GetDBField('OrgId') > 0) {
// new items or cloned items shouldn't be cloned again
return true;
}
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
$owner_field = $this->getOwnerField($event->Prefix);
if ($perm_helper->ModifyCheckPermission($object->GetDBField($owner_field), $object->GetDBField('CategoryId'), $event->Prefix) == 2) {
// 1. clone original item
$temp_handler =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$cloned_ids = $temp_handler->CloneItems($event->Prefix, $event->Special, Array($object->GetID()), null, null, null, true);
$ci_table = $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems');
// 2. delete record from CategoryItems (about cloned item) that was automatically created during call of Create method of kCatDBItem
$sql = 'SELECT ResourceId
FROM '.$object->TableName.'
WHERE '.$object->IDField.' = '.$cloned_ids[0];
$clone_resource_id = $this->Conn->GetOne($sql);
$sql = 'DELETE FROM '.$ci_table.'
WHERE ItemResourceId = '.$clone_resource_id.' AND PrimaryCat = 1';
$this->Conn->Query($sql);
// 3. copy main item categoryitems to cloned item
$sql = ' INSERT INTO '.$ci_table.' (CategoryId, ItemResourceId, PrimaryCat, ItemPrefix, Filename)
SELECT CategoryId, '.$clone_resource_id.' AS ItemResourceId, PrimaryCat, ItemPrefix, Filename
FROM '.$ci_table.'
WHERE ItemResourceId = '.$object->GetDBField('ResourceId');
$this->Conn->Query($sql);
// 4. put cloned id to OrgId field of item being cloned
$sql = 'UPDATE '.$object->TableName.'
SET OrgId = '.$object->GetID().'
WHERE '.$object->IDField.' = '.$cloned_ids[0];
$this->Conn->Query($sql);
// 5. substitute id of item being cloned with clone id
$this->Application->SetVar($event->getPrefixSpecial().'_id', $cloned_ids[0]);
$selected_ids = $this->getSelectedIDs($event, true);
$selected_ids[ array_search($object->GetID(), $selected_ids) ] = $cloned_ids[0];
$this->StoreSelectedIDs($event, $selected_ids);
// 6. delete original item from temp table
$temp_handler->DeleteItems($event->Prefix, $event->Special, Array($object->GetID()));
}
}
}
/**
* Sets default expiration based on module setting
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
parent::OnPreCreate($event);
if ($event->status == erSUCCESS) {
$object =& $event->getObject();
$owner_field = $this->getOwnerField($event->Prefix);
$object->SetDBField($owner_field, $this->Application->RecallVar('user_id'));
}
}
/**
* Occures before original item of item in pending editing got deleted (for hooking only)
*
* @param kEvent $event
*/
function OnBeforeDeleteOriginal(&$event)
{
}
/**
* Occures before an item is cloneded
* Id of ORIGINAL item is passed as event' 'id' param
* Do not call object' Update method in this event, just set needed fields!
*
* @param kEvent $event
*/
function OnBeforeClone(&$event)
{
if ($this->Application->GetVar('ResetCatBeforeClone')) {
$object =& $event->getObject();
$object->SetDBField('CategoryId', null);
}
}
/**
* Set status for new category item based on user permission in category
*
* @param kEvent $event
*/
function OnBeforeItemCreate(&$event)
{
if ($this->Application->IsAdmin()) {
return true;
}
$use_pending_editing = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($use_pending_editing) {
$object =& $event->getObject();
/* @var $object kDBItem */
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$primary_category = $object->GetDBField('CategoryId') > 0 ? $object->GetDBField('CategoryId') : $this->Application->GetVar('m_cat_id');
$item_status = $perm_helper->AddCheckPermission($primary_category, $event->Prefix);
if ($item_status == STATUS_DISABLED) {
$event->status = erFAIL;
return false;
}
else {
$object->SetDBField('Status', $item_status);
}
}
}
/**
* Creates category item & redirects to confirmation template (front-end only)
*
* @param kEvent $event
*/
function OnCreate(&$event)
{
parent::OnCreate($event);
$this->SetFrontRedirectTemplate($event, 'suggest');
}
/**
* Returns item's categories (allows to exclude primary category)
*
* @param int $resource_id
* @param bool $with_primary
* @return Array
*/
function getItemCategories($resource_id, $with_primary = false)
{
$sql = 'SELECT CategoryId
FROM '.TABLE_PREFIX.'CategoryItems
WHERE (ItemResourceId = '.$resource_id.')';
if (!$with_primary) {
$sql .= ' AND (PrimaryCat = 0)';
}
return $this->Conn->GetCol($sql);
}
/**
* Adds new and removes old additional categories from category item
*
* @param kCatDBItem $object
*/
function processAdditionalCategories(&$object, $mode)
{
$process_categories = $object->GetDBField('MoreCategories');
if ($process_categories === '') {
// field was not in submit & have default value (when no categories submitted, then value is null)
return ;
}
if ($mode == 'create') {
// prevents first additional category to become primary
$object->assignPrimaryCategory();
}
$process_categories = $process_categories ? explode('|', substr($process_categories, 1, -1)) : Array ();
$existing_categories = $this->getItemCategories($object->GetDBField('ResourceId'));
$add_categories = array_diff($process_categories, $existing_categories);
foreach ($add_categories as $category_id) {
$object->assignToCategory($category_id);
}
$remove_categories = array_diff($existing_categories, $process_categories);
foreach ($remove_categories as $category_id) {
$object->removeFromCategory($category_id);
}
}
/**
* Creates category item & redirects to confirmation template (front-end only)
*
* @param kEvent $event
*/
function OnUpdate(&$event)
{
$use_pending = $this->Application->getUnitOption($event->Prefix, 'UsePendingEditing');
if ($this->Application->IsAdmin() || !$use_pending) {
parent::OnUpdate($event);
$this->SetFrontRedirectTemplate($event, 'modify');
return ;
}
$object =& $event->getObject(Array('skip_autoload' => true));
/* @var $object kCatDBItem */
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ($items_info) {
$perm_helper =& $this->Application->recallObject('PermissionsHelper');
/* @var $perm_helper kPermissionsHelper */
$temp_handler =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $temp_handler kTempTablesHandler */
$owner_field = $this->getOwnerField($event->Prefix);
- $image_helper =& $this->Application->recallObject('ImageHelper');
- /* @var $image_helper ImageHelper */
+ $file_helper =& $this->Application->recallObject('FileHelper');
+ /* @var $file_helper FileHelper */
foreach ($items_info as $id => $field_values) {
$object->Load($id);
$edit_perm = $perm_helper->ModifyCheckPermission($object->GetDBField($owner_field), $object->GetDBField('CategoryId'), $event->Prefix);
if ($use_pending && !$object->GetDBField('OrgId') && ($edit_perm == STATUS_PENDING)) {
// pending editing enabled + not pending copy -> get/create pending copy & save changes to it
$original_id = $object->GetID();
$original_resource_id = $object->GetDBField('ResourceId');
- $image_helper->PreserveItemImages($field_values);
+ $file_helper->PreserveItemFiles($field_values);
$object->Load($original_id, 'OrgId');
if (!$object->isLoaded()) {
// 1. user has no pending copy of live item -> clone live item
$cloned_ids = $temp_handler->CloneItems($event->Prefix, $event->Special, Array($original_id), null, null, null, true);
$object->Load($cloned_ids[0]);
$object->SetFieldsFromHash($field_values);
// 1a. delete record from CategoryItems (about cloned item) that was automatically created during call of Create method of kCatDBItem
$ci_table = $this->Application->getUnitOption('ci', 'TableName');
$sql = 'DELETE FROM '.$ci_table.'
WHERE ItemResourceId = '.$object->GetDBField('ResourceId').' AND PrimaryCat = 1';
$this->Conn->Query($sql);
// 1b. copy main item categoryitems to cloned item
$sql = 'INSERT INTO '.$ci_table.' (CategoryId, ItemResourceId, PrimaryCat, ItemPrefix, Filename)
SELECT CategoryId, '.$object->GetDBField('ResourceId').' AS ItemResourceId, PrimaryCat, ItemPrefix, Filename
FROM '.$ci_table.'
WHERE ItemResourceId = '.$original_resource_id;
$this->Conn->Query($sql);
// 1c. put cloned id to OrgId field of item being cloned
$object->SetDBField('Status', STATUS_PENDING_EDITING);
$object->SetDBField('OrgId', $original_id);
}
else {
// 2. user has pending copy of live item -> just update field values
$object->SetFieldsFromHash($field_values);
}
// update id in request (used for redirect in mod-rewrite mode)
$this->Application->SetVar($event->getPrefixSpecial().'_id', $object->GetID());
}
else {
// 3. already editing pending copy -> just update field values
$object->SetFieldsFromHash($field_values);
}
if ($object->Update()) {
$event->status = erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->SetFrontRedirectTemplate($event, 'modify');
}
/**
* Sets next template to one required for front-end after adding/modifying item
*
* @param kEvent $event
* @param string $template_key - {suggest,modify}
*/
function SetFrontRedirectTemplate(&$event, $template_key)
{
if ($this->Application->IsAdmin() || $event->status != erSUCCESS) {
return ;
}
// prepare redirect template
$object =& $event->getObject();
$is_active = ($object->GetDBField('Status') == STATUS_ACTIVE);
$next_template = $is_active ? 'confirm_template' : 'pending_confirm_template';
$event->redirect = $this->Application->GetVar($template_key.'_'.$next_template);
$event->SetRedirectParam('opener', 's');
// send email events
$perm_prefix = $this->Application->getUnitOption($event->Prefix, 'PermItemPrefix');
switch ($event->Name) {
case 'OnCreate':
$event_suffix = $is_active ? 'ADD' : 'ADD.PENDING';
$owner_field = $this->getOwnerField($event->Prefix);
$this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix); // there are no ADD.PENDING event for admin :(
$this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField($owner_field));
break;
case 'OnUpdate':
$event_suffix = $is_active ? 'MODIFY' : 'MODIFY.PENDING';
$this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix); // there are no ADD.PENDING event for admin :(
$this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField('ModifiedById'));
break;
}
}
/**
* Apply same processing to each item beeing selected in grid
*
* @param kEvent $event
* @access private
*/
function iterateItems(&$event)
{
if ($event->Name != 'OnMassApprove' && $event->Name != 'OnMassDecline') {
return parent::iterateItems($event);
}
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
foreach ($ids as $id) {
$object->Load($id);
switch ($event->Name) {
case 'OnMassApprove':
$ret = $object->ApproveChanges();
break;
case 'OnMassDecline':
$ret = $object->DeclineChanges();
break;
}
if (!$ret) {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->clearSelectedIDs($event);
}
/**
* Deletes items & preserves clean env
*
* @param kEvent $event
*/
function OnDelete(&$event)
{
parent::OnDelete($event);
if ($event->status == erSUCCESS && !$this->Application->IsAdmin()) {
$event->SetRedirectParam('pass', 'm');
$event->SetRedirectParam('m_cat_id', 0);
}
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
*/
function checkItemStatus(&$event)
{
$object =& $event->getObject();
if (!$object->isLoaded()) {
return true;
}
$status = $object->GetDBField('Status');
$user_id = $this->Application->RecallVar('user_id');
$owner_field = $this->getOwnerField($event->Prefix);
if (($status == -2 || $status == STATUS_PENDING) && ($object->GetDBField($owner_field) == $user_id)) {
return true;
}
return $status == STATUS_ACTIVE;
}
/**
* Set sorting directly to session
*
* @param kEvent $event
*/
function OnSetSortingDirect(&$event)
{
$combined = $this->Application->GetVar($event->Prefix.'_CombinedSorting');
if ($combined) {
list($field, $dir) = explode('|', $combined);
$this->Application->StoreVar($event->Prefix.'_Sort1', $field);
$this->Application->StoreVar($event->Prefix.'_Sort1_Dir', $dir);
return ;
}
$field_pos = $this->Application->GetVar($event->Prefix.'_SortPos');
$this->Application->LinkVar($event->Prefix.'_Sort'.$field_pos, $event->Prefix.'_Sort'.$field_pos);
$this->Application->LinkVar($event->Prefix.'_Sort'.$field_pos.'_Dir', $event->Prefix.'_Sort'.$field_pos.'_Dir');
}
/**
* Set's correct sorting for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetSorting(&$event)
{
if (!$this->Application->IsAdmin()) {
$event->setEventParam('same_special', true);
}
parent::SetSorting($event);
}
/**
* Returns current per-page setting for list
*
* @param kEvent $event
* @return int
*/
function getPerPage(&$event)
{
if (!$this->Application->IsAdmin()) {
$event->setEventParam('same_special', true);
}
return parent::getPerPage($event);
}
function getOwnerField($prefix)
{
$owner_field = $this->Application->getUnitOption($prefix, 'OwnerField');
if (!$owner_field) {
$owner_field = 'CreatedById';
}
return $owner_field;
}
/**
* Creates virtual image fields for item
*
* @param kEvent $event
*/
function OnAfterConfigRead(&$event)
{
- $image_helper =& $this->Application->recallObject('ImageHelper');
- /* @var $image_helper ImageHelper */
+ $file_helper =& $this->Application->recallObject('FileHelper');
+ /* @var $file_helper FileHelper */
- $image_helper->createItemImages($event->Prefix);
+ $file_helper->createItemFiles($event->Prefix, true); // create image fields
+ $file_helper->createItemFiles($event->Prefix, false); // create file fields
}
+ /**
+ * Returns file contents associated with item
+ *
+ * @param kEvent $event
+ */
+ function OnDownloadFile(&$event)
+ {
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
+
+ $event->status = erSTOP;
+
+ $field = $this->Application->GetVar('field');
+ if (!preg_match('/^File([\d]+)/', $field)) {
+ return ;
+ }
+
+ $filename = $object->GetField($field, 'full_path');
+
+ $content_type = function_exists('mime_content_type') ? mime_content_type($filename) : 'application/octet-stream';
+
+ header('Content-type: '.$content_type);
+ header('Content-Disposition: attachment; filename="'.basename($filename).'"');
+ header('Content-Length: '.filesize($filename));
+ readfile($filename);
+ flush();
+ }
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/general/cat_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.97.2.6
\ No newline at end of property
+1.97.2.7
\ No newline at end of property

Event Timeline