Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Fri, Feb 21, 4:07 PM

in-portal

Index: branches/RC/core/kernel/utility/formatters/upload_formatter.php
===================================================================
--- branches/RC/core/kernel/utility/formatters/upload_formatter.php (revision 11720)
+++ branches/RC/core/kernel/utility/formatters/upload_formatter.php (revision 11721)
@@ -1,318 +1,318 @@
<?php
class kUploadFormatter extends kFormatter
{
var $DestinationPath;
var $FullPath;
function kUploadFormatter()
{
parent::kBase();
if ($this->DestinationPath) {
$this->FullPath = FULL_PATH.$this->DestinationPath;
}
}
/**
* Processes file uploads from form
*
* @param mixed $value
* @param string $field_name
* @param kDBItem $object
* @return string
*/
function Parse($value, $field_name, &$object)
{
$ret = !is_array($value) ? $value : '';
$options = $object->GetFieldOptions($field_name);
if (getArrayValue($options, 'upload_dir')) {
$this->DestinationPath = $options['upload_dir'];
$this->FullPath = FULL_PATH.$this->DestinationPath;
}
// SWF Uploader
if (is_array($value) && isset($value['tmp_ids'])) {
if ($value['tmp_deleted']) {
$deleted = explode('|', $value['tmp_deleted']);
$upload = explode('|', $value['upload']);
$n_upload = array();
// $n_ids = array();
foreach ($upload as $name) {
if (in_array($name, $deleted)) continue;
$n_upload[] = $name;
// $n_ids[] = $name;
}
$value['upload'] = implode('|', $n_upload);
// $value['tmp_ids'] = implode('|', $n_ids);
}
if (!$value['tmp_ids']) {
// no pending files -> return already uploded files
return getArrayValue($value, 'upload');
}
$swf_uploaded_ids = explode('|', $value['tmp_ids']);
$swf_uploaded_names = explode('|', $value['tmp_names']);
$existing = $value['upload'] ? explode('|', $value['upload']) : array();
if (isset($options['multiple'])) {
$max_files = $options['multiple'] == false ? 1 : $options['multiple'];
}
else {
$max_files = 1;
}
$fret = array();
// don't delete uploaded file, when it's name matches delete file name
$var_name = $object->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$schedule = $this->Application->RecallVar($var_name);
$schedule = $schedule ? unserialize($schedule) : Array();
$files2delete = Array();
foreach ($schedule as $data) {
if ($data['action'] == 'delete') {
$files2delete[] = $data['file'];
}
}
for ($i=0; $i<min($max_files, count($swf_uploaded_ids)); $i++) {
$real_name = $swf_uploaded_names[$i];
$real_name = $this->ValidateFileName($this->FullPath, $real_name, $files2delete);
$file_name = $this->FullPath.$real_name;
$tmp_file = (defined('WRITEABLE') ? WRITEABLE.'/tmp/' : FULL_PATH.'/kernel/cache/').$swf_uploaded_ids[$i].'_'.$swf_uploaded_names[$i];
rename($tmp_file, $file_name);
@chmod($file_name, 0666);
$fret[] = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath.$real_name;
}
$fret = array_merge($existing, $fret);
return implode('|', $fret);
}
// SWF Uploader END
if (getArrayValue($value, 'upload') && getArrayValue($value, 'error') == UPLOAD_ERR_NO_FILE) {
// file was not uploaded this time, but was uploaded before, then use previously uploaded file (from db)
return getArrayValue($value, 'upload');
}
if (is_array($value) && count($value) > 1 && $value['size']) {
if (is_array($value) && $value['error'] === UPLOAD_ERR_OK) {
$max_filesize = isset($options['max_size']) ? $options['max_size'] : MAX_UPLOAD_SIZE;
if (getArrayValue($options, 'allowed_types') && !in_array($value['type'], $options['allowed_types'])) {
$error_params = Array (
'file_type' => $value['type'],
'allowed_types' => $options['allowed_types'],
);
$object->SetError($field_name, 'bad_file_format', 'la_error_InvalidFileFormat', $error_params);
}
elseif ($value['size'] > $max_filesize) {
$object->SetError($field_name, 'bad_file_size', 'la_error_FileTooLarge');
}
elseif (!is_writable($this->FullPath)) {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
else {
$real_name = $this->ValidateFileName($this->FullPath, $value['name']);
$file_name = $this->FullPath.$real_name;
if (!move_uploaded_file($value['tmp_name'], $file_name)) {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
else {
@chmod($file_name, 0666);
if (getArrayValue($options, 'size_field')) {
$object->SetDBField($options['size_field'], $value['size']);
}
if (getArrayValue($options, 'orig_name_field')) {
$object->SetDBField($options['orig_name_field'], $value['name']);
}
if (getArrayValue($options, 'content_type_field')) {
$object->SetDBField($options['content_type_field'], $value['type']);
}
$ret = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath.$real_name;
// delete previous file, when new file is uploaded under same field
/*$previous_file = isset($value['upload']) ? $value['upload'] : false;
if ($previous_file && file_exists($this->FullPath.$previous_file)) {
unlink($this->FullPath.$previous_file);
}*/
}
}
}
else {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file');
}
}
if ((count($value) > 1) && $value['error'] && ($value['error'] != UPLOAD_ERR_NO_FILE)) {
$object->SetError($field_name, 'cant_save_file', 'la_error_cant_save_file', $value);
}
return $ret;
}
function getSingleFormat($format)
{
$single_mapping = Array (
'file_urls' => 'full_url',
'file_paths' => 'full_path',
'file_sizes' => 'file_size',
'files_resized' => 'resize',
'img_sizes' => 'img_size',
'wms' => 'wm',
);
return $single_mapping[$format];
}
/**
* Return formatted file url,path or size (or same for multiple files)
*
* @param string $value
* @param string $field_name
* @param kDBItem $object
* @param string $format
* @return string
*/
function Format($value, $field_name, &$object, $format = null)
{
if (is_null($value)) {
return '';
}
$options = $object->GetFieldOptions($field_name);
if (!isset($format)) {
$format = isset($options['format']) ? $options['format'] : false;
}
if ($format && preg_match('/(file_urls|file_paths|file_names|file_sizes|img_sizes|files_resized|wms)(.*)/', $format, $regs)) {
if (!$value || $format == 'file_names') {
// storage format matches display format OR no value
return $value;
}
$ret = Array ();
$files = explode('|', $value);
$format = $this->getSingleFormat($regs[1]).$regs[2];
foreach ($files as $a_file) {
$ret[] = $this->GetFormatted($a_file, $field_name, $object, $format);
}
return implode('|', $ret);
}
$tc_value = $this->TypeCast($value, $options);
if( ($tc_value === false) || ($tc_value != $value) ) return $value; // for leaving badly formatted date on the form
$object->Fields[$field_name]['direct_links'] = true; // for case, when non-swf uploader is used
return $this->GetFormatted($tc_value, $field_name, $object, $format);
}
/**
* Return formatted file url,path or size
*
* @param string $value
* @param string $field_name
* @param kDBItem $object
* @param string $format
* @return string
*/
function GetFormatted($value, $field_name, &$object, $format = null)
{
if (!$format) {
return $value;
}
$options = $object->GetFieldOptions($field_name);
$upload_dir = isset($options['upload_dir']) ? $options['upload_dir'] : $this->DestinationPath;
if (preg_match('/resize:([\d]*)x([\d]*)/', $format, $regs)) {
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
- return $image_helper->ResizeImage(FULL_PATH.$upload_dir.$value, $format);
+ return $image_helper->ResizeImage(FULL_PATH . str_replace('/', DIRECTORY_SEPARATOR, $upload_dir) . $value, $format);
}
switch ($format) {
case 'full_url':
if (isset($options['direct_links']) && $options['direct_links']) {
- return rtrim($this->Application->BaseURL(), '/').$upload_dir.$value;
+ return rtrim($this->Application->BaseURL(), '/') . str_replace(DIRECTORY_SEPARATOR, '/', $upload_dir) . $value;
}
else {
$url_params = Array (
'no_amp' => 1, 'pass' => 'm,'.$object->Prefix,
$object->Prefix.'_event' => 'OnViewFile',
'file' => $value, 'field' => $field_name
);
return $this->Application->HREF('', '', $url_params);
}
break;
case 'full_path':
- return FULL_PATH.$upload_dir.$value;
+ return FULL_PATH . str_replace('/', DIRECTORY_SEPARATOR, $upload_dir) . $value;
break;
case 'file_size':
- return filesize(FULL_PATH.$upload_dir.$value);
+ return filesize(FULL_PATH . str_replace('/', DIRECTORY_SEPARATOR, $upload_dir) . $value);
break;
case 'img_size':
$image_helper =& $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
- $image_info = $image_helper->getImageInfo(FULL_PATH . $upload_dir . $value);
+ $image_info = $image_helper->getImageInfo(FULL_PATH . str_replace('/', DIRECTORY_SEPARATOR, $upload_dir) . $value);
return $image_info ? $image_info[3] : '';
break;
}
return sprintf($format, $value);
}
function ValidateFileName($path, $name, $forbidden_names = Array())
{
$parts = pathinfo($name);
$ext = '.'.$parts['extension'];
$filename = mb_substr($parts['basename'], 0, -mb_strlen($ext));
$new_name = $filename.$ext;
while ( file_exists($path.'/'.$new_name) || in_array(rtrim($path, '/').'/'.$new_name, $forbidden_names) )
{
if ( preg_match('/('.preg_quote($filename, '/').'_)([0-9]*)('.preg_quote($ext, '/').')/', $new_name, $regs) ) {
$new_name = $regs[1].($regs[2]+1).$regs[3];
}
else {
$new_name = $filename.'_1'.$ext;
}
}
return $new_name;
}
}
class kPictureFormatter extends kUploadFormatter
{
function kPictureFormatter()
{
$this->NakeLookupPath = IMAGES_PATH; // used ?
$this->DestinationPath = constOn('ADMIN') ? IMAGES_PENDING_PATH : IMAGES_PATH;
parent::kUploadFormatter();
}
function GetFormatted($value, $field_name, &$object, $format = null)
{
if ($format == 'img_size') {
$upload_dir = isset($options['upload_dir']) ? $options['upload_dir'] : $this->DestinationPath;
$img_path = FULL_PATH.'/'.$upload_dir.$value;
$image_info = @getimagesize($img_path);
return ' width="'.$image_info[0].'" height="'.$image_info[1].'"';
}
return parent::GetFormatted($value, $field_name, $object, $format);
}
}
\ No newline at end of file
Property changes on: branches/RC/core/kernel/utility/formatters/upload_formatter.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.10.2.17
\ No newline at end of property
+1.10.2.18
\ No newline at end of property
Index: branches/RC/core/kernel/db/db_event_handler.php
===================================================================
--- branches/RC/core/kernel/db/db_event_handler.php (revision 11720)
+++ branches/RC/core/kernel/db/db_event_handler.php (revision 11721)
@@ -1,2441 +1,2442 @@
<?php
define('EH_CUSTOM_PROCESSING_BEFORE',1);
define('EH_CUSTOM_PROCESSING_AFTER',2);
/**
* Note:
* 1. When adressing variables from submit containing
* Prefix_Special as part of their name use
* $event->getPrefixSpecial(true) instead of
* $event->Prefix_Special as usual. This is due PHP
* is converting "." symbols in variable names during
* submit info "_". $event->getPrefixSpecial optional
* 1st parameter returns correct corrent Prefix_Special
* for variables beeing submitted such way (e.g. variable
* name that will be converted by PHP: "users.read_only_id"
* will be submitted as "users_read_only_id".
*
* 2. When using $this->Application-LinkVar on variables submitted
* from form which contain $Prefix_Special then note 1st item. Example:
* LinkVar($event->getPrefixSpecial(true).'_varname',$event->Prefix_Special.'_varname')
*
*/
/**
* EventHandler that is used to process
* any database related events
*
*/
class kDBEventHandler extends kEventHandler {
/**
* Description
*
* @var kDBConnection
* @access public
*/
var $Conn;
/**
* Adds ability to address db connection
*
* @return kDBEventHandler
* @access public
*/
function kDBEventHandler()
{
parent::kBase();
$this->Conn =& $this->Application->GetADODBConnection();
}
/**
* Checks permissions of user
*
* @param kEvent $event
*/
function CheckPermission(&$event)
{
if (!$this->Application->IsAdmin()) {
$allow_events = Array('OnSearch', 'OnSearchReset', 'OnNew');
if (in_array($event->Name, $allow_events)) {
// allow search on front
return true;
}
}
$section = $event->getSection();
if (!preg_match('/^CATEGORY:(.*)/', $section)) {
// only if not category item events
if ((substr($event->Name, 0, 9) == 'OnPreSave') || ($event->Name == 'OnSave')) {
if ($this->isNewItemCreate($event)) {
return $this->Application->CheckPermission($section.'.add', 1);
}
else {
return $this->Application->CheckPermission($section.'.add', 1) || $this->Application->CheckPermission($section.'.edit', 1);
}
}
}
if ($event->Name == 'OnPreCreate') {
// save category_id before item create (for item category selector not to destroy permission checking category)
$this->Application->LinkVar('m_cat_id');
}
if ($event->Name == 'OnSaveWidths') {
return $this->Application->IsAdmin() && $this->Application->LoggedIn();
}
return parent::CheckPermission($event);
}
/**
* Allows to override standart permission mapping
*
*/
function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnLoad' => Array('self' => 'view', 'subitem' => 'view'),
'OnItemBuild' => Array('self' => 'view', 'subitem' => 'view'),
'OnBuild' => Array('self' => true),
'OnNew' => Array('self' => 'add', 'subitem' => 'add|edit'),
'OnCreate' => Array('self' => 'add', 'subitem' => 'add|edit'),
'OnUpdate' => Array('self' => 'edit', 'subitem' => 'add|edit'),
'OnSetPrimary' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnDelete' => Array('self' => 'delete', 'subitem' => 'add|edit'),
'OnDeleteAll' => Array('self' => 'delete', 'subitem' => 'add|edit'),
'OnMassDelete' => Array('self' => 'delete', 'subitem' => 'add|edit'),
'OnMassClone' => Array('self' => 'add', 'subitem' => 'add|edit'),
'OnCut' => array('self'=>'edit', 'subitem' => 'edit'),
'OnCopy' => array('self'=>'edit', 'subitem' => 'edit'),
'OnPaste' => array('self'=>'edit', 'subitem' => 'edit'),
'OnSelectItems' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnProcessSelected' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnSelectUser' => Array('self' => 'add|edit', 'subitem' => 'add|edit'),
'OnMassApprove' => Array('self' => 'advanced:approve|edit', 'subitem' => 'advanced:approve|add|edit'),
'OnMassDecline' => Array('self' => 'advanced:decline|edit', 'subitem' => 'advanced:decline|add|edit'),
'OnMassMoveUp' => Array('self' => 'advanced:move_up|edit', 'subitem' => 'advanced:move_up|add|edit'),
'OnMassMoveDown' => Array('self' => 'advanced:move_down|edit', 'subitem' => 'advanced:move_down|add|edit'),
'OnPreCreate' => Array('self' => 'add|add.pending', 'subitem' => 'edit|edit.pending'),
'OnEdit' => Array('self' => 'edit|edit.pending', 'subitem' => 'edit|edit.pending'),
'OnExport' => Array('self' => 'view|advanced:export'),
'OnExportBegin' => Array('self' => 'view|advanced:export'),
'OnExportProgress' => Array('self' => 'view|advanced:export'),
'OnSetAutoRefreshInterval' => Array ('self' => true, 'subitem' => true),
'OnAutoRefreshToggle' => Array ('self' => true, 'subitem' => true),
// theese event do not harm, but just in case check them too :)
'OnCancelEdit' => Array('self' => true, 'subitem' => true),
'OnCancel' => Array('self' => true, 'subitem' => true),
'OnReset' => Array('self' => true, 'subitem' => true),
'OnSetSorting' => Array('self' => true, 'subitem' => true),
'OnSetSortingDirect' => Array('self' => true, 'subitem' => true),
'OnResetSorting' => Array('self' => true, 'subitem' => true),
'OnSetFilter' => Array('self' => true, 'subitem' => true),
'OnApplyFilters' => Array('self' => true, 'subitem' => true),
'OnRemoveFilters' => Array('self' => true, 'subitem' => true),
'OnSetFilterPattern' => Array('self' => true, 'subitem' => true),
'OnSetPerPage' => Array('self' => true, 'subitem' => true),
'OnSearch' => Array('self' => true, 'subitem' => true),
'OnSearchReset' => Array('self' => true, 'subitem' => true),
'OnGoBack' => Array('self' => true, 'subitem' => true),
// it checks permission itself since flash uploader does not send cookies
'OnUploadFile' => Array ('self' => true, 'subitem' => true),
'OnDeleteFile' => Array ('self' => true, 'subitem' => true),
'OnViewFile' => Array ('self' => true, 'subitem' => true),
'OnSaveWidths' => Array ('self' => true, 'subitem' => true),
'OnValidateMInputFields' => Array ('self' => 'view'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
function mapEvents()
{
$events_map = Array(
'OnRemoveFilters' => 'FilterAction',
'OnApplyFilters' => 'FilterAction',
'OnMassApprove'=>'iterateItems',
'OnMassDecline'=>'iterateItems',
'OnMassMoveUp'=>'iterateItems',
'OnMassMoveDown'=>'iterateItems',
);
$this->eventMethods = array_merge($this->eventMethods, $events_map);
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
*/
function getPassedID(&$event)
{
if ($event->getEventParam('raise_warnings') === false) {
$event->setEventParam('raise_warnings', 1);
}
if (preg_match('/^auto-(.*)/', $event->Special, $regs) && $this->Application->prefixRegistred($regs[1])) {
// <inp2:lang.auto-phrase_Field name="DateFormat"/> - returns field DateFormat value from language (LanguageId is extracted from current phrase object)
$main_object =& $this->Application->recallObject($regs[1]);
/* @var $main_object kDBItem */
$id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
return $main_object->GetDBField($id_field);
}
// 1. get id from post (used in admin)
$ret = $this->Application->GetVar($event->getPrefixSpecial(true).'_id');
if ($ret) {
return $ret;
}
// 2. get id from env (used in front)
$ret = $this->Application->GetVar($event->getPrefixSpecial().'_id');
if ($ret) {
return $ret;
}
// recall selected ids array and use the first one
$ids = $this->Application->GetVar($event->getPrefixSpecial().'_selected_ids');
if ($ids != '') {
$ids = explode(',',$ids);
if ($ids) {
$ret = array_shift($ids);
}
}
else { // if selected ids are not yet stored
$this->StoreSelectedIDs($event);
return $this->Application->GetVar($event->getPrefixSpecial(true).'_id'); // StoreSelectedIDs sets this variable
}
return $ret;
}
/**
* Prepares and stores selected_ids string
* in Session and Application Variables
* by getting all checked ids from grid plus
* id passed in get/post as prefix_id
*
* @param kEvent $event
* @param Array $ids
*
* @return Array ids stored
*/
function StoreSelectedIDs(&$event, $ids = null)
{
$wid = $this->Application->GetTopmostWid($event->Prefix);
$session_name = rtrim($event->getPrefixSpecial().'_selected_ids_'.$wid, '_');
if (isset($ids)) {
// save ids directly if they given
$this->Application->StoreVar($session_name, implode(',', $ids));
return $ids;
}
$ret = Array();
// May be we don't need this part: ?
$passed = $this->Application->GetVar($event->getPrefixSpecial(true).'_id');
if($passed !== false && $passed != '')
{
array_push($ret, $passed);
}
$ids = Array();
// get selected ids from post & save them to session
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
$id_field = $this->Application->getUnitOption($event->Prefix,'IDField');
foreach($items_info as $id => $field_values)
{
if( getArrayValue($field_values,$id_field) ) array_push($ids,$id);
}
//$ids=array_keys($items_info);
}
$ret = array_unique(array_merge($ret, $ids));
$this->Application->SetVar($event->getPrefixSpecial().'_selected_ids', implode(',',$ret));
$this->Application->LinkVar($event->getPrefixSpecial().'_selected_ids', $session_name);
// This is critical - otherwise getPassedID will return last ID stored in session! (not exactly true)
// this smells... needs to be refactored
$first_id = getArrayValue($ret,0);
if (($first_id === false) && ($event->getEventParam('raise_warnings') == 1)) {
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('Requested ID for prefix <b>'.$event->getPrefixSpecial().'</b> <span class="debug_error">not passed</span>',E_USER_NOTICE);
}
$this->Application->SetVar($event->getPrefixSpecial(true).'_id', $first_id);
return $ret;
}
/**
* Returns stored selected ids as an array
*
* @param kEvent $event
* @param bool $from_session return ids from session (written, when editing was started)
* @return array
*/
function getSelectedIDs(&$event, $from_session = false)
{
if ($from_session) {
$wid = $this->Application->GetTopmostWid($event->Prefix);
$var_name = rtrim($event->getPrefixSpecial().'_selected_ids_'.$wid, '_');
$ret = $this->Application->RecallVar($var_name);
}
else {
$ret = $this->Application->GetVar($event->getPrefixSpecial().'_selected_ids');
}
return explode(',', $ret);
}
/**
* Returs associative array of submitted fields for current item
* Could be used while creating/editing single item -
* meaning on any edit form, except grid edit
*
* @param kEvent $event
*/
function getSubmittedFields(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
$field_values = $items_info ? array_shift($items_info) : Array();
return $field_values;
}
/**
* Removes any information about current/selected ids
* from Application variables and Session
*
* @param kEvent $event
*/
function clearSelectedIDs(&$event)
{
$prefix_special = $event->getPrefixSpecial();
$ids = implode(',', $this->getSelectedIDs($event, true));
$event->setEventParam('ids', $ids);
$wid = $this->Application->GetTopmostWid($event->Prefix);
$session_name = rtrim($prefix_special.'_selected_ids_'.$wid, '_');
$this->Application->RemoveVar($session_name);
$this->Application->SetVar($prefix_special.'_selected_ids', '');
$this->Application->SetVar($prefix_special.'_id', ''); // $event->getPrefixSpecial(true).'_id' too may be
}
/*function SetSaveEvent(&$event)
{
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnUpdate');
$this->Application->LinkVar($event->Prefix_Special.'_SaveEvent');
}*/
/**
* Common builder part for Item & List
*
* @param kDBBase $object
* @param kEvent $event
* @access private
*/
function dbBuild(&$object, &$event)
{
$object->Configure( $event->getEventParam('populate_ml_fields') || $this->Application->getUnitOption($event->Prefix, 'PopulateMlFields') );
$this->PrepareObject($object, $event);
// force live table if specified or is original item
$live_table = $event->getEventParam('live_table') || $event->Special == 'original';
if( $this->UseTempTables($event) && !$live_table )
{
$object->SwitchToTemp();
}
// This strange constuction creates hidden field for storing event name in form submit
// It pass SaveEvent to next screen, otherwise after unsuccsefull create it will try to update rather than create
$current_event = $this->Application->GetVar($event->Prefix_Special.'_event');
// $this->Application->setEvent($event->Prefix_Special, $current_event);
$this->Application->setEvent($event->Prefix_Special, '');
$save_event = $this->UseTempTables($event) && $this->Application->GetTopmostPrefix($event->Prefix) == $event->Prefix ? 'OnSave' : 'OnUpdate';
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent',$save_event);
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
*/
function checkItemStatus(&$event)
{
$status_fields = $this->Application->getUnitOption($event->Prefix,'StatusField');
if (!$status_fields) {
return true;
}
$status_field = array_shift($status_fields);
if ($status_field == 'Status' || $status_field == 'Enabled') {
$object =& $event->getObject();
if (!$object->isLoaded()) {
return true;
}
return $object->GetDBField($status_field) == STATUS_ACTIVE;
}
return true;
}
/**
* Shows not found template content
*
* @param kEvent $event
*
*/
function _errorNotFound(&$event)
{
if ($event->getEventParam('raise_warnings') === 0) {
// when it's possible, that autoload fails do nothing
return ;
}
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('ItemLoad Permission Failed for prefix [' . $event->getPrefixSpecial() . '] in <strong>checkItemStatus</strong>, leading to "404 Not Found"', E_USER_WARNING);
header('HTTP/1.0 404 Not Found');
while (ob_get_level()) {
ob_end_clean();
}
// object is used inside template parsing, so break out any parsing and return error document
$error_template = $this->Application->ConfigValue('ErrorTemplate');
$themes_helper =& $this->Application->recallObject('ThemesHelper');
/* @var $themes_helper kThemesHelper */
$this->Application->SetVar('t', $error_template);
$this->Application->SetVar('m_cat_id', $themes_helper->getPageByTemplate($error_template));
$this->Application->HTML = $this->Application->ParseBlock( Array ('name' => $error_template) );
$this->Application->Done();
exit;
}
/**
* Builds item (loads if needed)
*
* @param kEvent $event
* @access protected
*/
function OnItemBuild(&$event)
{
$object =& $event->getObject();
$this->dbBuild($object,$event);
$sql = $this->ItemPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
// 2. loads if allowed
$auto_load = $this->Application->getUnitOption($event->Prefix,'AutoLoad');
$skip_autload = $event->getEventParam('skip_autoload');
if ($auto_load && !$skip_autload) {
$perm_status = true;
$user_id = $this->Application->RecallVar('user_id');
$event->setEventParam('top_prefix', $this->Application->GetTopmostPrefix($event->Prefix, true));
$status_checked = false;
if ($user_id == -1 || $this->CheckPermission($event)) {
// don't autoload item, when user doesn't have view permission
$this->LoadItem($event);
$status_checked = true;
if ($user_id != -1 && !$this->Application->IsAdmin() && !$this->checkItemStatus($event)) {
$perm_status = false;
}
}
else {
$perm_status = false;
}
if (!$perm_status) {
// when no permission to view item -> redirect to no pemrission template
if ($this->Application->isDebugMode()) {
$this->Application->Debugger->appendTrace();
}
trigger_error('ItemLoad Permission Failed for prefix ['.$event->getPrefixSpecial().'] in <strong>'.($status_checked ? 'checkItemStatus' : 'CheckPermission').'</strong>', E_USER_WARNING);
$next_template = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate');
$this->Application->Redirect($next_template, Array('next_template' => $this->Application->GetVar('t')));
}
}
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_GoTab', '');
$actions->Set($event->Prefix_Special.'_GoId', '');
}
/**
* Build subtables array from configs
*
* @param kEvent $event
*/
function OnTempHandlerBuild(&$event)
{
$object =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $object kTempTablesHandler */
$object->BuildTables( $event->Prefix, $this->getSelectedIDs($event) );
}
/**
* Checks, that object used in event should use temp tables
*
* @param kEvent $event
* @return bool
*/
function UseTempTables(&$event)
{
return $this->Application->IsTempMode($event->Prefix, $event->Special);
}
/**
* Returns table prefix from event (temp or live)
*
* @param kEvent $event
* @return string
* @todo Needed? Should be refactored (by Alex)
*/
function TablePrefix(&$event)
{
return $this->UseTempTables($event) ? $this->Application->GetTempTablePrefix('prefix:'.$event->Prefix).TABLE_PREFIX : TABLE_PREFIX;
}
/**
* Load item if id is available
*
* @param kEvent $event
*/
function LoadItem(&$event)
{
$object =& $event->getObject();
$id = $this->getPassedID($event);
- if ($object->isLoaded() && ($object->GetID() == $id)) {
+ if ($object->isLoaded() && !is_array($id) && ($object->GetID() == $id)) {
// object is already loaded by same id
return ;
}
if ($object->Load($id)) {
$actions =& $this->Application->recallObject('kActions');
$actions->Set($event->Prefix_Special.'_id', $object->GetID() );
}
else {
$object->setID($id);
}
}
/**
* Builds list
*
* @param kEvent $event
* @access protected
*/
function OnListBuild(&$event)
{
$object =& $event->getObject();
/* @var $object kDBList */
$this->dbBuild($object,$event);
$sql = $this->ListPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
$object->Counted = false; // when requery="1" should re-count records too!
$object->ClearOrderFields(); // prevents duplicate order fields, when using requery="1"
$object->linkToParent( $this->getMainSpecial($event) );
$this->AddFilters($event);
$this->SetCustomQuery($event); // new!, use this for dynamic queries based on specials for ex.
$this->SetPagination($event);
$this->SetSorting($event);
// $object->CalculateTotals(); // Now called in getTotals to avoid extra query
$actions =& $this->Application->recallObject('kActions');
$actions->Set('remove_specials['.$event->Prefix_Special.']', '0');
$actions->Set($event->Prefix_Special.'_GoTab', '');
}
/**
* Get's special of main item for linking with subitem
*
* @param kEvent $event
* @return string
*/
function getMainSpecial(&$event)
{
$special = $event->getEventParam('main_special');
if($special === false || $special == '$main_special')
{
$special = $event->Special;
}
return $special;
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @access protected
* @see OnListBuild
*/
function SetCustomQuery(&$event)
{
}
/**
* Set's new perpage for grid
*
* @param kEvent $event
*/
function OnSetPerPage(&$event)
{
$per_page = $this->Application->GetVar($event->getPrefixSpecial(true).'_PerPage');
$this->Application->StoreVar($event->getPrefixSpecial().'_PerPage', $per_page);
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_PerPage.'.$view_name, $per_page);
}
/**
* 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) {
$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;
}
}
/*$per_page = $event->getEventParam('per_page');
if ($per_page == 'list_next') {
$cur_page = $page;
$cur_per_page = $per_page;
$object->SetPerPage(1);
$object =& $this->Application->recallObject($event->Prefix);
$cur_item_index = $object->CurrentIndex;
$page = ($cur_page-1) * $cur_per_page + $cur_item_index + 1;
$object->SetPerPage(1);
}*/
$object->SetPage($page);
}
/**
* Returns current per-page setting for list
*
* @param kEvent $event
* @return int
*/
function getPerPage(&$event)
{
// 1. per-page is passed as tag parameter to PrintList, InitList, etc.
$per_page = $event->getEventParam('per_page');
/*if ($per_page == 'list_next') {
$per_page = '';
}*/
// 2. per-page variable name is store into config variable
$config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
if ($config_mapping) {
switch ( $per_page ){
case 'short_list' :
$per_page = $this->Application->ConfigValue($config_mapping['ShortListPerPage']);
break;
case 'default' :
$per_page = $this->Application->ConfigValue($config_mapping['PerPage']);
break;
}
}
if (!$per_page) {
// per-page is stored to persistent session
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$storage_prefix = $event->getEventParam('same_special') ? $event->Prefix : $event->getPrefixSpecial();
$per_page = $this->Application->RecallPersistentVar($storage_prefix.'_PerPage.'.$view_name, ALLOW_DEFAULT_SETTINGS);
if (!$per_page) {
// per-page is stored to current session
$per_page = $this->Application->RecallVar($storage_prefix.'_PerPage');
}
if (!$per_page) {
if ($config_mapping) {
if (!isset($config_mapping['PerPage'])) {
trigger_error('Incorrect mapping of <span class="debug_error">PerPage</span> key in config for prefix <b>'.$event->Prefix.'</b>', E_USER_WARNING);
}
$per_page = $this->Application->ConfigValue($config_mapping['PerPage']);
}
if (!$per_page) {
// none of checked above per-page locations are useful, then try default value
$default_per_page = $event->getEventParam('default_per_page');
$per_page = is_numeric($default_per_page) ? $default_per_page : 10;
}
}
}
return $per_page;
}
/**
* Set's correct sorting for list
* based on data provided with event
*
* @param kEvent $event
* @access private
* @see OnListBuild
*/
function SetSorting(&$event)
{
$event->setPseudoClass('_List');
$object =& $event->getObject();
$storage_prefix = $event->getEventParam('same_special') ? $event->Prefix : $event->Prefix_Special;
$cur_sort1 = $this->Application->RecallVar($storage_prefix.'_Sort1');
$cur_sort1_dir = $this->Application->RecallVar($storage_prefix.'_Sort1_Dir');
$cur_sort2 = $this->Application->RecallVar($storage_prefix.'_Sort2');
$cur_sort2_dir = $this->Application->RecallVar($storage_prefix.'_Sort2_Dir');
$sorting_configs = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping');
$list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings');
$sorting_prefix = getArrayValue($list_sortings, $event->Special) ? $event->Special : '';
$tag_sort_by = $event->getEventParam('sort_by');
if ($tag_sort_by) {
if ($tag_sort_by == 'random') {
$object->AddOrderField('RAND()', '');
}
else {
$tag_sort_by = explode('|', $tag_sort_by);
foreach ($tag_sort_by as $sorting_element) {
list ($by, $dir) = explode(',', $sorting_element);
$object->AddOrderField($by, $dir);
}
}
}
if ($sorting_configs && isset ($sorting_configs['DefaultSorting1Field'])){
$list_sortings[$sorting_prefix]['Sorting'] = Array(
$this->Application->ConfigValue($sorting_configs['DefaultSorting1Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting1Dir']),
$this->Application->ConfigValue($sorting_configs['DefaultSorting2Field']) => $this->Application->ConfigValue($sorting_configs['DefaultSorting2Dir']),
);
}
// Use default if not specified
if ( !$cur_sort1 || !$cur_sort1_dir)
{
if ( $sorting = getArrayValue($list_sortings, $sorting_prefix, 'Sorting') ) {
reset($sorting);
$cur_sort1 = key($sorting);
$cur_sort1_dir = current($sorting);
if (next($sorting)) {
$cur_sort2 = key($sorting);
$cur_sort2_dir = current($sorting);
}
}
}
if ( $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting') ) {
foreach ($forced_sorting as $field => $dir) {
$object->AddOrderField($field, $dir);
}
}
if($cur_sort1 != '' && $cur_sort1_dir != '')
{
$object->AddOrderField($cur_sort1, $cur_sort1_dir);
}
if($cur_sort2 != '' && $cur_sort2_dir != '')
{
$object->AddOrderField($cur_sort2, $cur_sort2_dir);
}
}
/**
* Add filters found in session
*
* @param kEvent $event
*/
function AddFilters(&$event)
{
$object =& $event->getObject();
$edit_mark = rtrim($this->Application->GetSID().'_'.$this->Application->GetTopmostWid($event->Prefix), '_');
// add search filter
$filter_data = $this->Application->RecallVar($event->getPrefixSpecial().'_search_filter');
if ($filter_data) {
$filter_data = unserialize($filter_data);
foreach ($filter_data as $filter_field => $filter_params) {
$filter_type = ($filter_params['type'] == 'having') ? HAVING_FILTER : WHERE_FILTER;
$filter_value = str_replace(EDIT_MARK, $edit_mark, $filter_params['value']);
$object->addFilter($filter_field, $filter_value, $filter_type, FLT_SEARCH);
}
}
// add custom filter
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name);
if ($custom_filters) {
$grid_name = $event->getEventParam('grid');
$custom_filters = unserialize($custom_filters);
if (isset($custom_filters[$grid_name])) {
foreach ($custom_filters[$grid_name] as $field_name => $field_options) {
list ($filter_type, $field_options) = each($field_options);
if (isset($field_options['value']) && $field_options['value']) {
$filter_type = ($field_options['sql_filter_type'] == 'having') ? HAVING_FILTER : WHERE_FILTER;
$filter_value = str_replace(EDIT_MARK, $edit_mark, $field_options['value']);
$object->addFilter($field_name, $filter_value, $filter_type, FLT_CUSTOM);
}
}
}
}
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
if($view_filter)
{
$view_filter = unserialize($view_filter);
$temp_filter =& $this->Application->makeClass('kMultipleFilter');
$filter_menu = $this->Application->getUnitOption($event->Prefix,'FilterMenu');
$group_key = 0; $group_count = count($filter_menu['Groups']);
while($group_key < $group_count)
{
$group_info = $filter_menu['Groups'][$group_key];
$temp_filter->setType( constant('FLT_TYPE_'.$group_info['mode']) );
$temp_filter->clearFilters();
foreach ($group_info['filters'] as $flt_id)
{
$sql_key = getArrayValue($view_filter,$flt_id) ? 'on_sql' : 'off_sql';
if ($filter_menu['Filters'][$flt_id][$sql_key] != '')
{
$temp_filter->addFilter('view_filter_'.$flt_id, $filter_menu['Filters'][$flt_id][$sql_key]);
}
}
$object->addFilter('view_group_'.$group_key, $temp_filter, $group_info['type'] , FLT_VIEW);
$group_key++;
}
}
}
/**
* Set's new sorting for list
*
* @param kEvent $event
* @access protected
*/
function OnSetSorting(&$event)
{
$cur_sort1 = $this->Application->RecallVar($event->Prefix_Special.'_Sort1');
$cur_sort1_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort1_Dir');
$use_double_sorting = $this->Application->ConfigValue('UseDoubleSorting');
if ($use_double_sorting) {
$cur_sort2 = $this->Application->RecallVar($event->Prefix_Special.'_Sort2');
$cur_sort2_dir = $this->Application->RecallVar($event->Prefix_Special.'_Sort2_Dir');
}
$passed_sort1 = $this->Application->GetVar($event->getPrefixSpecial(true).'_Sort1');
if ($cur_sort1 == $passed_sort1) {
$cur_sort1_dir = $cur_sort1_dir == 'asc' ? 'desc' : 'asc';
}
else {
if ($use_double_sorting) {
$cur_sort2 = $cur_sort1;
$cur_sort2_dir = $cur_sort1_dir;
}
$cur_sort1 = $passed_sort1;
$cur_sort1_dir = 'asc';
}
$this->Application->StoreVar($event->Prefix_Special.'_Sort1', $cur_sort1);
$this->Application->StoreVar($event->Prefix_Special.'_Sort1_Dir', $cur_sort1_dir);
if ($use_double_sorting) {
$this->Application->StoreVar($event->Prefix_Special.'_Sort2', $cur_sort2);
$this->Application->StoreVar($event->Prefix_Special.'_Sort2_Dir', $cur_sort2_dir);
}
}
/**
* Set sorting directly to session (used for category item sorting (front-end), grid sorting (admin, view menu)
*
* @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');
}
/**
* Reset grid sorting to default (from config)
*
* @param kEvent $event
*/
function OnResetSorting(&$event)
{
$this->Application->RemoveVar($event->Prefix_Special.'_Sort1');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort1_Dir');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort2');
$this->Application->RemoveVar($event->Prefix_Special.'_Sort2_Dir');
}
/**
* Sets grid refresh interval
*
* @param kEvent $event
*/
function OnSetAutoRefreshInterval(&$event)
{
$refresh_interval = $this->Application->GetVar('refresh_interval');
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_refresh_interval.'.$view_name, $refresh_interval);
}
/**
* Changes auto-refresh state for grid
*
* @param kEvent $event
*/
function OnAutoRefreshToggle(&$event)
{
$refresh_intervals = $this->Application->ConfigValue('AutoRefreshIntervals');
if (!$refresh_intervals) {
return ;
}
$view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view');
$auto_refresh = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_auto_refresh.'.$view_name);
if ($auto_refresh === false) {
$refresh_intervals = explode(',', $refresh_intervals);
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_refresh_interval.'.$view_name, $refresh_intervals[0]);
}
$this->Application->StorePersistentVar($event->getPrefixSpecial().'_auto_refresh.'.$view_name, $auto_refresh ? 0 : 1);
}
/**
* Creates needed sql query to load item,
* if no query is defined in config for
* special requested, then use default
* query
*
* @param kEvent $event
* @access protected
*/
function ItemPrepareQuery(&$event)
{
$sqls = $this->Application->getUnitOption($event->Prefix, 'ItemSQLs', Array ());
$special = array_key_exists($event->Special, $sqls) ? $event->Special : '';
if (!array_key_exists($special, $sqls)) {
// preferred special not found in ItemSQLs -> use analog from ListSQLs
return $this->ListPrepareQuery($event);
}
return $sqls[$special];
}
/**
* Creates needed sql query to load list,
* if no query is defined in config for
* special requested, then use default
* query
*
* @param kEvent $event
* @access protected
*/
function ListPrepareQuery(&$event)
{
$sqls = $this->Application->getUnitOption($event->Prefix, 'ListSQLs', Array ());
return $sqls[ array_key_exists($event->Special, $sqls) ? $event->Special : '' ];
}
/**
* Apply custom processing to item
*
* @param kEvent $event
*/
function customProcessing(&$event, $type)
{
}
/* Edit Events mostly used in Admin */
/**
* Creates new kDBItem
*
* @param kEvent $event
* @access protected
*/
function OnCreate(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
list($id,$field_values) = each($items_info);
$object->SetFieldsFromHash($field_values);
}
$this->customProcessing($event,'before');
//look at kDBItem' Create for ForceCreateId description, it's rarely used and is NOT set by default
if( $object->Create($event->getEventParam('ForceCreateId')) )
{
if( $object->IsTempTable() ) $object->setTempID();
$this->customProcessing($event,'after');
$event->status=erSUCCESS;
$event->redirect_params = Array('opener'=>'u');
}
else
{
$event->status = erFAIL;
$event->redirect = false;
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent','OnCreate');
$object->setID($id);
}
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @access protected
*/
function OnUpdate(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
foreach($items_info as $id => $field_values)
{
$object->Load($id);
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
break;
}
}
}
$event->redirect_params = Array('opener'=>'u');
}
/**
* Delete's kDBItem object
*
* @param kEvent $event
* @access protected
*/
function OnDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $temp kTempTablesHandler */
$temp->DeleteItems($event->Prefix, $event->Special, Array($this->getPassedID($event)));
}
/**
* Deletes all records from table
*
* @param kEvent $event
*/
function OnDeleteAll(&$event)
{
$sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . '
FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName');
$ids = $this->Conn->GetCol($sql);
if ($ids) {
$temp_handler =& $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler');
/* @var $temp_handler kTempTablesHandler */
$temp_handler->DeleteItems($event->Prefix, $event->Special, $ids);
}
}
/**
* Prepares new kDBItem object
*
* @param kEvent $event
* @access protected
*/
function OnNew(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$object->Clear(0);
$this->Application->SetVar($event->Prefix_Special.'_SaveEvent', 'OnCreate');
$table_info = $object->getLinkedInfo();
$object->SetDBField($table_info['ForeignKey'], $table_info['ParentId']);
$event->redirect = false;
}
/**
* Cancel's kDBItem Editing/Creation
*
* @param kEvent $event
* @access protected
*/
function OnCancel(&$event)
{
$object =& $event->getObject(Array('skip_autoload' => true));
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ($items_info) {
$delete_ids = Array();
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
foreach ($items_info as $id => $field_values) {
$object->Load($id);
// record created for using with selector (e.g. Reviews->Select User), and not validated => Delete it
if ($object->isLoaded() && !$object->Validate() && ($id <= 0) ) {
$delete_ids[] = $id;
}
}
if ($delete_ids) {
$temp->DeleteItems($event->Prefix, $event->Special, $delete_ids);
}
}
$event->redirect_params = Array('opener'=>'u');
}
/**
* Deletes all selected items.
* Automatically recurse into sub-items using temp handler, and deletes sub-items
* by calling its Delete method if sub-item has AutoDelete set to true in its config file
*
* @param kEvent $event
*/
function OnMassDelete(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$event->status=erSUCCESS;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$ids = $this->StoreSelectedIDs($event);
$event->setEventParam('ids', $ids);
$this->customProcessing($event, 'before');
$ids = $event->getEventParam('ids');
if($ids)
{
$temp->DeleteItems($event->Prefix, $event->Special, $ids);
}
$this->clearSelectedIDs($event);
}
/**
* Sets window id (of first opened edit window) to temp mark in uls
*
* @param kEvent $event
*/
function setTempWindowID(&$event)
{
$mode = $this->Application->GetVar($event->Prefix.'_mode');
if ($mode == 't') {
$wid = $this->Application->GetVar('m_wid');
$this->Application->SetVar($event->Prefix.'_mode', 't'.$wid);
}
}
/**
* Prepare temp tables and populate it
* with items selected in the grid
*
* @param kEvent $event
*/
function OnEdit(&$event)
{
$this->setTempWindowID($event);
$this->StoreSelectedIDs($event);
$var_name = $event->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$this->Application->RemoveVar($var_name);
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
/* @var $temp kTempTablesHandler */
$temp->PrepareEdit();
$event->redirect=false;
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
*/
function OnSave(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$skip_master = false;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$changes_var_name = $this->Prefix.'_changes_'.$this->Application->GetTopmostWid($this->Prefix);
if (!$this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$live_ids = $temp->SaveEdit($event->getEventParam('master_ids') ? $event->getEventParam('master_ids') : Array());
// Deleteing files scheduled for delete
$var_name = $event->getPrefixSpecial().'_file_pending_actions'.$this->Application->GetVar('m_wid');
$schedule = $this->Application->RecallVar($var_name);
$schedule = $schedule ? unserialize($schedule) : array();
foreach ($schedule as $data) {
if ($data['action'] == 'delete') {
unlink($data['file']);
}
}
if ($live_ids) {
// ensure, that newly created item ids are avalable as if they were selected from grid
// NOTE: only works if main item has subitems !!!
$this->StoreSelectedIDs($event, $live_ids);
}
$this->SaveLoggedChanges($changes_var_name);
}
else {
$this->Application->RemoveVar($changes_var_name);
}
$this->clearSelectedIDs($event);
$event->redirect_params = Array('opener' => 'u');
$this->Application->RemoveVar($event->getPrefixSpecial().'_modified');
// all temp tables are deleted here => all after hooks should think, that it's live mode now
$this->Application->SetVar($event->Prefix.'_mode', '');
}
}
function SaveLoggedChanges($changes_var_name)
{
$ses_log_id = $this->Application->RecallVar('_SessionLogId_');
if (!$ses_log_id) {
return ;
}
$changes = $this->Application->RecallVar($changes_var_name);
$changes = $changes ? unserialize($changes) : Array ();
if (!$changes) {
return ;
}
$add_fields = Array (
'PortalUserId' => $this->Application->RecallVar('user_id'),
'SessionLogId' => $ses_log_id,
);
$changelog_table = $this->Application->getUnitOption('change-log', 'TableName');
$sessionlog_table = $this->Application->getUnitOption('session-log', 'TableName');
foreach ($changes as $rec) {
$this->Conn->doInsert(array_merge($rec, $add_fields), $changelog_table);
}
$sql = 'UPDATE '.$sessionlog_table.'
SET AffectedItems = AffectedItems + '.count($changes).'
WHERE SessionLogId = '.$ses_log_id;
$this->Conn->Query($sql);
$this->Application->RemoveVar($changes_var_name);
}
/**
* Cancels edit
* Removes all temp tables and clears selected ids
*
* @param kEvent $event
*/
function OnCancelEdit(&$event)
{
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp->CancelEdit();
$this->clearSelectedIDs($event);
$event->redirect_params = Array('opener'=>'u');
$this->Application->RemoveVar($event->getPrefixSpecial().'_modified');
}
/**
* Allows to determine if we are creating new item or editing already created item
*
* @param kEvent $event
* @return bool
*/
function isNewItemCreate(&$event)
{
$object =& $event->getObject( Array ('raise_warnings' => 0) );
return !$object->IsLoaded();
// $item_id = $this->getPassedID($event);
// return ($item_id == '') ? true : false;
}
/**
* Saves edited item into temp table
* If there is no id, new item is created in temp table
*
* @param kEvent $event
*/
function OnPreSave(&$event)
{
//$event->redirect = false;
// if there is no id - it means we need to create an item
if (is_object($event->MasterEvent)) {
$event->MasterEvent->setEventParam('IsNew',false);
}
if ($this->isNewItemCreate($event)) {
$event->CallSubEvent('OnPreSaveCreated');
if (is_object($event->MasterEvent)) {
$event->MasterEvent->setEventParam('IsNew',true);
}
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if ($items_info) {
foreach ($items_info as $id => $field_values) {
$object->SetDefaultValues();
$object->Load($id);
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
}
/**
* [HOOK] Saves subitem
*
* @param kEvent $event
*/
function OnPreSaveSubItem(&$event)
{
$not_created = $this->isNewItemCreate($event);
$event->CallSubEvent($not_created ? 'OnCreate' : 'OnUpdate');
if ($event->status == erSUCCESS) {
$object =& $event->getObject();
/* @var $object kDBItem */
$this->Application->SetVar($event->getPrefixSpecial() . '_id', $object->GetID());
}
$event->SetRedirectParam('opener', 's');
}
/**
* Saves edited item in temp table and loads
* item with passed id in current template
* Used in Prev/Next buttons
*
* @param kEvent $event
*/
function OnPreSaveAndGo(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$event->SetRedirectParam($event->getPrefixSpecial(true).'_id', $this->Application->GetVar($event->Prefix_Special.'_GoId'));
}
}
/**
* Saves edited item in temp table and goes
* to passed tabs, by redirecting to it with OnPreSave event
*
* @param kEvent $event
*/
function OnPreSaveAndGoToTab(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status==erSUCCESS) {
$event->redirect=$this->Application->GetVar($event->getPrefixSpecial(true).'_GoTab');
}
}
/**
* Saves editable list and goes to passed tab,
* by redirecting to it with empty event
*
* @param kEvent $event
*/
function OnUpdateAndGoToTab(&$event)
{
$event->setPseudoClass('_List');
$event->CallSubEvent('OnUpdate');
if ($event->status==erSUCCESS) {
$event->redirect=$this->Application->GetVar($event->getPrefixSpecial(true).'_GoTab');
}
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
*/
function OnPreCreate(&$event)
{
$this->setTempWindowID($event);
$this->clearSelectedIDs($event);
$object =& $event->getObject( Array('skip_autoload' => true) );
$temp =& $this->Application->recallObject($event->Prefix.'_TempHandler', 'kTempTablesHandler');
$temp->PrepareEdit();
$object->setID(0);
$this->Application->SetVar($event->getPrefixSpecial().'_id',0);
$this->Application->SetVar($event->getPrefixSpecial().'_PreCreate', 1);
$event->redirect=false;
}
/**
* Creates a new item in temp table and
* stores item id in App vars and Session on succsess
*
* @param kEvent $event
*/
function OnPreSaveCreated(&$event)
{
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info) $field_values = array_shift($items_info);
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values);
$this->customProcessing($event, 'before');
if( $object->Create() )
{
$this->customProcessing($event, 'after');
$event->redirect_params[$event->getPrefixSpecial(true).'_id'] = $object->GetId();
$event->status=erSUCCESS;
}
else
{
$event->status=erFAIL;
$event->redirect=false;
$object->setID(0);
}
}
function OnReset(&$event)
{
//do nothing - should reset :)
if ($this->isNewItemCreate($event)) {
// just reset id to 0 in case it was create
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->setID(0);
$this->Application->SetVar($event->getPrefixSpecial().'_id',0);
}
}
/**
* Apply same processing to each item beeing selected in grid
*
* @param kEvent $event
* @access private
*/
function iterateItems(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$object =& $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$status_field = array_shift( $this->Application->getUnitOption($event->Prefix,'StatusField') );
$order_field = $this->Application->getUnitOption($event->Prefix,'OrderField');
if (!$order_field) {
$order_field = 'Priority';
}
foreach ($ids as $id) {
$object->Load($id);
switch ($event->Name) {
case 'OnMassApprove':
$object->SetDBField($status_field, 1);
break;
case 'OnMassDecline':
$object->SetDBField($status_field, 0);
break;
case 'OnMassMoveUp':
$object->SetDBField($order_field, $object->GetDBField($order_field) + 1);
break;
case 'OnMassMoveDown':
$object->SetDBField($order_field, $object->GetDBField($order_field) - 1);
break;
}
if ($object->Update()) {
$event->status = erSUCCESS;
}
else {
$event->status = erFAIL;
$event->redirect = false;
break;
}
}
}
$this->clearSelectedIDs($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnMassClone(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$event->status = erSUCCESS;
$temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$temp->CloneItems($event->Prefix, $event->Special, $ids);
}
$this->clearSelectedIDs($event);
}
function check_array($records, $field, $value)
{
foreach ($records as $record) {
if ($record[$field] == $value) {
return true;
}
}
return false;
}
function OnPreSavePopup(&$event)
{
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
$this->finalizePopup($event);
}
/* End of Edit events */
// III. Events that allow to put some code before and after Update,Load,Create and Delete methods of item
/**
* Occurse before loading item, 'id' parameter
* allows to get id of item beeing loaded
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemLoad(&$event)
{
}
/**
* Occurse after loading item, 'id' parameter
* allows to get id of item that was loaded
*
* @param kEvent $event
* @access public
*/
function OnAfterItemLoad(&$event)
{
}
/**
* Occurse before creating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemCreate(&$event)
{
}
/**
* Occurse after creating item
*
* @param kEvent $event
* @access public
*/
function OnAfterItemCreate(&$event)
{
}
/**
* Occurse before updating item
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemUpdate(&$event)
{
}
/**
* Occurse after updating item
*
* @param kEvent $event
* @access public
*/
function OnAfterItemUpdate(&$event)
{
}
/**
* Occurse before deleting item, id of item beeing
* deleted is stored as 'id' event param
*
* @param kEvent $event
* @access public
*/
function OnBeforeItemDelete(&$event)
{
}
/**
* Occurse after deleting item, id of deleted item
* is stored as 'id' param of event
*
* @param kEvent $event
* @access public
*/
function OnAfterItemDelete(&$event)
{
}
/**
* Occurs after successful item validation
*
* @param kEvent $event
*/
function OnAfterItemValidate(&$event)
{
}
/**
* Occures after an item has been copied to temp
* Id of copied item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterCopyToTemp(&$event)
{
}
/**
* Occures before an item is deleted from live table when copying from temp
* (temp handler deleted all items from live and then copy over all items from temp)
* Id of item being deleted is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnBeforeDeleteFromLive(&$event)
{
}
/**
* Occures before an item is copied to live table (after all foreign keys have been updated)
* Id of item being copied is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnBeforeCopyToLive(&$event)
{
}
/**
* !!! NOT FULLY IMPLEMENTED - SEE TEMP HANDLER COMMENTS (search by event name)!!!
* Occures after an item has been copied to live table
* Id of copied item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterCopyToLive(&$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)
{
}
/**
* Occures after an item has been cloned
* Id of newly created item is passed as event' 'id' param
*
* @param kEvent $event
*/
function OnAfterClone(&$event)
{
}
/**
* Occures after list is queried
*
* @param kEvent $event
*/
function OnAfterListQuery(&$event)
{
}
/**
* Ensures that popup will be closed automatically
* and parent window will be refreshed with template
* passed
*
* @param kEvent $event
* @access public
*/
function finalizePopup(&$event)
{
$event->SetRedirectParam('opener', 'u');
}
/**
* Create search filters based on search query
*
* @param kEvent $event
* @access protected
*/
function OnSearch(&$event)
{
$event->setPseudoClass('_List');
$search_helper =& $this->Application->recallObject('SearchHelper');
/* @var $search_helper kSearchHelper */
$search_helper->performSearch($event);
}
/**
* Clear search keywords
*
* @param kEvent $event
* @access protected
*/
function OnSearchReset(&$event)
{
$search_helper =& $this->Application->recallObject('SearchHelper');
/* @var $search_helper kSearchHelper */
$search_helper->resetSearch($event);
}
/**
* Set's new filter value (filter_id meaning from config)
*
* @param kEvent $event
*/
function OnSetFilter(&$event)
{
$filter_id = $this->Application->GetVar('filter_id');
$filter_value = $this->Application->GetVar('filter_value');
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
$view_filter = $view_filter ? unserialize($view_filter) : Array();
$view_filter[$filter_id] = $filter_value;
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
}
function OnSetFilterPattern(&$event)
{
$filters = $this->Application->GetVar($event->getPrefixSpecial(true).'_filters');
if (!$filters) return ;
$view_filter = $this->Application->RecallVar($event->getPrefixSpecial().'_view_filter');
$view_filter = $view_filter ? unserialize($view_filter) : Array();
$filters = explode(',', $filters);
foreach ($filters as $a_filter) {
list($id, $value) = explode('=', $a_filter);
$view_filter[$id] = $value;
}
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
$event->redirect = false;
}
/**
* Add/Remove all filters applied to list from "View" menu
*
* @param kEvent $event
*/
function FilterAction(&$event)
{
$view_filter = Array();
$filter_menu = $this->Application->getUnitOption($event->Prefix,'FilterMenu');
switch ($event->Name)
{
case 'OnRemoveFilters':
$filter_value = 1;
break;
case 'OnApplyFilters':
$filter_value = 0;
break;
}
foreach($filter_menu['Filters'] as $filter_key => $filter_params)
{
if(!$filter_params) continue;
$view_filter[$filter_key] = $filter_value;
}
$this->Application->StoreVar( $event->getPrefixSpecial().'_view_filter', serialize($view_filter) );
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnPreSaveAndOpenTranslator(&$event)
{
$this->Application->SetVar('allow_translation', true);
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$resource_id = $this->Application->GetVar('translator_resource_id');
if ($resource_id) {
$t_prefixes = explode(',', $this->Application->GetVar('translator_prefixes'));
$cdata =& $this->Application->recallObject($t_prefixes[1], null, Array('skip_autoload' => true));
$cdata->Load($resource_id, 'ResourceId');
if (!$cdata->isLoaded()) {
$cdata->SetDBField('ResourceId', $resource_id);
$cdata->Create();
}
$this->Application->SetVar($cdata->getPrefixSpecial().'_id', $cdata->GetID());
}
$event->redirect = $this->Application->GetVar('translator_t');
$event->redirect_params = Array('pass'=>'all,trans,'.$this->Application->GetVar('translator_prefixes'),
$event->getPrefixSpecial(true).'_id' => $object->GetID(),
'trans_event' => 'OnLoad',
'trans_prefix' => $this->Application->GetVar('translator_prefixes'),
'trans_field' => $this->Application->GetVar('translator_field'),
'trans_multi_line' => $this->Application->GetVar('translator_multi_line'),
);
// 1. SAVE LAST TEMPLATE TO SESSION (really needed here, because of tweaky redirect)
$last_template = $this->Application->RecallVar('last_template');
preg_match('/index4\.php\|'.$this->Application->GetSID().'-(.*):/U', $last_template, $rets);
$this->Application->StoreVar('return_template', $this->Application->GetVar('t'));
}
}
function RemoveRequiredFields(&$object)
{
// making all field non-required to achieve successful presave
foreach($object->Fields as $field => $options)
{
if(isset($options['required']))
{
unset($object->Fields[$field]['required']);
}
}
}
/**
* Saves selected user in needed field
*
* @param kEvent $event
*/
function OnSelectUser(&$event)
{
$items_info = $this->Application->GetVar('u');
if ($items_info) {
$user_id = array_shift( array_keys($items_info) );
$object =& $event->getObject();
$this->RemoveRequiredFields($object);
$is_new = !$object->isLoaded();
$is_main = substr($this->Application->GetVar($event->Prefix.'_mode'), 0, 1) == 't';
if ($is_new) {
$new_event = $is_main ? 'OnPreCreate' : 'OnNew';
$event->CallSubEvent($new_event);
$event->redirect = true;
}
$object->SetDBField($this->Application->RecallVar('dst_field'), $user_id);
if ($is_new) {
$object->Create();
if (!$is_main && $object->IsTempTable()) {
$object->setTempID();
}
}
else {
$object->Update();
}
}
$event->SetRedirectParam($event->getPrefixSpecial().'_id', $object->GetID());
$this->finalizePopup($event);
}
/** EXPORT RELATED **/
/**
* Shows export dialog
*
* @param kEvent $event
*/
function OnExport(&$event)
{
$selected_ids = $this->StoreSelectedIDs($event);
if (implode(',', $selected_ids) == '') {
// K4 fix when no ids found bad selected ids array is formed
$selected_ids = false;
}
$this->Application->StoreVar($event->Prefix.'_export_ids', $selected_ids ? implode(',', $selected_ids) : '' );
$this->Application->LinkVar('export_finish_t');
$this->Application->LinkVar('export_progress_t');
$this->Application->StoreVar('export_oroginal_special', $event->Special);
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
/*list ($index_file, $env) = explode('|', $this->Application->RecallVar('last_template'));
$finish_url = $this->Application->BaseURL('/admin').$index_file.'?'.ENV_VAR_NAME.'='.$env;
$this->Application->StoreVar('export_finish_url', $finish_url);*/
$redirect_params = Array (
$this->Prefix . '.export_event' => 'OnNew',
'pass' => 'all,' . $this->Prefix . '.export'
);
$event->setRedirectParams($redirect_params);
}
/**
* Apply some special processing to
* object beeing recalled before using
* it in other events that call prepareObject
*
* @param Object $object
* @param kEvent $event
* @access protected
*/
function prepareObject(&$object, &$event)
{
if ($event->Special == 'export' || $event->Special == 'import')
{
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
/* @var $export_helper kCatDBItemExportHelper */
$export_helper->prepareExportColumns($event);
}
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
*/
function getCustomExportColumns(&$event)
{
return Array();
}
/**
* Export form validation & processing
*
* @param kEvent $event
*/
function OnExportBegin(&$event)
{
$export_helper =& $this->Application->recallObject('CatItemExportHelper');
/* @var $export_helper kCatDBItemExportHelper */
$export_helper->OnExportBegin($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnExportCancel(&$event)
{
$this->OnGoBack($event);
}
/**
* Allows configuring export options
*
* @param kEvent $event
*/
function OnBeforeExportBegin(&$event)
{
}
function OnDeleteExportPreset(&$event)
{
$object =& $event->GetObject();
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
list($id,$field_values) = each($items_info);
$preset_key = $field_values['ExportPresets'];
$export_settings = $this->Application->RecallPersistentVar('export_settings');
if (!$export_settings) return ;
$export_settings = unserialize($export_settings);
if (!isset($export_settings[$event->Prefix])) return ;
$to_delete = '';
$export_presets = array(''=>'');
foreach ($export_settings[$event->Prefix] as $key => $val) {
if (implode('|', $val['ExportColumns']) == $preset_key) {
$to_delete = $key;
break;
}
}
if ($to_delete) {
unset($export_settings[$event->Prefix][$to_delete]);
$this->Application->StorePersistentVar('export_settings', serialize($export_settings));
}
}
}
/**
* Saves changes & changes language
*
* @param kEvent $event
*/
function OnPreSaveAndChangeLanguage(&$event)
{
$event->CallSubEvent('OnPreSave');
if ($event->status == erSUCCESS) {
$this->Application->SetVar('m_lang', $this->Application->GetVar('language'));
$pass_vars = Array ('st_id', 'cms_id');
foreach ($pass_vars as $pass_var) {
$data = $this->Application->GetVar($pass_var);
if ($data) {
$event->SetRedirectParam($pass_var, $data);
}
}
}
}
/**
* Used to save files uploaded via swfuploader
*
* @param kEvent $event
*/
function OnUploadFile(&$event)
{
$event->status = erSTOP;
define('DBG_SKIP_REPORTING', 1);
echo "Flash requires that we output something or it won't fire the uploadSuccess event";
if (!$this->Application->HttpQuery->Post) {
// Variables {field, id, flashsid} are always submitted through POST!
// When file size is larger, then "upload_max_filesize" (in php.ini),
// then theese variables also are not submitted -> handle such case.
header('HTTP/1.0 413 File size exceeds allowed limit');
return ;
}
if (!$this->_checkFlashUploaderPermission($event)) {
// 403 Forbidden
header('HTTP/1.0 403 You don\'t have permissions to upload');
return ;
}
$value = $this->Application->GetVar('Filedata');
if (!$value || ($value['error'] != UPLOAD_ERR_OK)) {
// 413 Request Entity Too Large (file uploads disabled OR uploaded file was
// to large for web server to accept, see "upload_max_filesize" in php.ini)
header('HTTP/1.0 413 File size exceeds allowed limit');
return ;
}
$tmp_path = defined('WRITEABLE') ? WRITEABLE.'/tmp/' : FULL_PATH.'/kernel/cache/';
$fname = $value['name'];
$id = $this->Application->GetVar('id');
if ($id) {
$fname = $id.'_'.$fname;
}
$fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
$upload_dir = $fields[ $this->Application->GetVar('field') ]['upload_dir'];
if (!is_writable($tmp_path) || !is_writable(FULL_PATH . $upload_dir)) {
// 500 Internal Server Error
// check both temp and live upload directory
header('HTTP/1.0 500 Write permissions not set on the server');
return ;
}
move_uploaded_file($value['tmp_name'], $tmp_path.$fname);
}
/**
* Checks, that flash uploader is allowed to perform upload
*
* @param kEvent $event
* @return bool
*/
function _checkFlashUploaderPermission(&$event)
{
// Flash uploader does NOT send correct cookies, so we need to make our own check
$cookie_name = 'adm_' . $this->Application->ConfigValue('SessionCookieName');
$this->Application->HttpQuery->Cookie['cookies_on'] = 1;
$this->Application->HttpQuery->Cookie[$cookie_name] = $this->Application->GetVar('flashsid');
// this prevents session from auto-expiring when KeepSessionOnBrowserClose & FireFox is used
$this->Application->HttpQuery->Cookie[$cookie_name . '_live'] = $this->Application->GetVar('flashsid');
$admin_ses =& $this->Application->recallObject('Session.admin');
/* @var $admin_ses Session */
$backup_user_id = $this->Application->RecallVar('user_id'); // 1. backup user
$this->Application->StoreVar('user_id', $admin_ses->RecallVar('user_id')); // 2. fake user_id
$check_event = new kEvent($event->getPrefixSpecial() . ':OnProcessSelected'); // 3. event, that have "add|edit" rule
$allowed_to_upload = $this->CheckPermission($check_event); // 4. check permission
$this->Application->StoreVar('user_id', $backup_user_id); // 5. restore user id
return $allowed_to_upload;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnDeleteFile(&$event)
{
$event->status = erSTOP;
if (strpos($this->Application->GetVar('file'), '../') !== false) {
return ;
}
$object =& $event->getObject( Array ('skip_autoload' => true) );
$options = $object->GetFieldOptions( $this->Application->GetVar('field') );
$var_name = $event->getPrefixSpecial() . '_file_pending_actions' . $this->Application->GetVar('m_wid');
$schedule = $this->Application->RecallVar($var_name);
$schedule = $schedule ? unserialize($schedule) : Array ();
$schedule[] = Array ('action' => 'delete', 'file' => $path = FULL_PATH . $options['upload_dir'] . $this->Application->GetVar('file'));
$this->Application->StoreVar($var_name, serialize($schedule));
$this->Application->Session->SaveData();
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnViewFile(&$event)
{
if (strpos($this->Application->GetVar('file'), '../') !== false) return ;
if ($this->Application->GetVar('tmp')) {
$path = (defined('WRITEABLE') ? WRITEABLE.'/tmp/' : FULL_PATH.'/kernel/cache/').$this->Application->GetVar('id').'_'.$this->Application->GetVar('file');
}
else {
$object =& $event->getObject(array('skip_autoload'=>true));
$options = $object->GetFieldOptions($this->Application->GetVar('field'));
$path = FULL_PATH.$options['upload_dir'].$this->Application->GetVar('file');
}
+ $path = str_replace('/', DIRECTORY_SEPARATOR, $path);
$type = mime_content_type($path);
header('Content-Length: '.filesize($path));
header('Content-Type: '.$type);
safeDefine('DBG_SKIP_REPORTING',1);
readfile($path);
exit();
}
/**
* Validates MInput control fields
*
* @param kEvent $event
*/
function OnValidateMInputFields(&$event)
{
$minput_helper =& $this->Application->recallObject('MInputHelper');
/* @var $minput_helper MInputHelper */
$minput_helper->OnValidateMInputFields($event);
}
/**
* Returns auto-complete values for ajax-dropdown
*
* @param kEvent $event
*/
function OnSuggestValues(&$event)
{
$this->Application->XMLHeader();
$field = $this->Application->GetVar('field');
$cur_value = $this->Application->GetVar('cur_value');
if (!$field || !$cur_value) {
exit;
}
$limit = $this->Application->GetVar('limit');
if (!$limit) {
$limit = 20;
}
$object =& $event->getObject();
$sql = 'SELECT DISTINCT '.$field.'
FROM '.$object->TableName.'
WHERE '.$field.' LIKE '.$this->Conn->qstr($cur_value.'%').'
ORDER BY '.$field.'
LIMIT 0,' . $limit;
$data = $this->Conn->GetCol($sql);
echo '<suggestions>';
foreach ($data as $item) {
echo '<item>' . htmlspecialchars($item) . '</item>';
}
echo '</suggestions>';
$event->status = erSTOP;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSaveWidths(&$event)
{
$event->status = erSTOP;
$lang =& $this->Application->recallObject('lang.current');
// header('Content-type: text/xml; charset='.$lang->GetDBField('Charset'));
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
/* @var $picker_helper kColumnPickerHelper */
$picker_helper->PreparePicker($event->getPrefixSpecial(), $this->Application->GetVar('grid_name'));
$picker_helper->SaveWidths($event->getPrefixSpecial(), $this->Application->GetVar('widths'));
echo 'OK';
}
/**
* Called from CSV import script after item fields
* are set and validated, but before actual item create/update.
* If event status is erSUCCESS, line will be imported,
* else it will not be imported but added to skipped lines
* and displayed in the end of import.
* Event status is preset from import script.
*
* @param kEvent $event
*/
function OnBeforeCSVLineImport(&$event)
{
// abstract, for hooking
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/kernel/db/db_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.99.2.49
\ No newline at end of property
+1.99.2.50
\ No newline at end of property
Index: branches/RC/core/units/skins/skin_eh.php
===================================================================
--- branches/RC/core/units/skins/skin_eh.php (revision 11720)
+++ branches/RC/core/units/skins/skin_eh.php (revision 11721)
@@ -1,91 +1,116 @@
<?php
class SkinEventHandler extends kDBEventHandler {
+ function mapPermissions()
+ {
+ parent::mapPermissions();
+ $permissions = Array (
+ 'OnItemBuild' => Array ('self' => true),
+ );
+
+ $this->permMapping = array_merge($this->permMapping, $permissions);
+ }
+
+ /**
+ * With "primary" special loads primary skin
+ *
+ * @param kEvent $event
+ * @return int
+ */
+ function getPassedID(&$event)
+ {
+ if ($event->Special == 'primary') {
+ return Array ('IsPrimary' => 1);
+ }
+
+ return parent::getPassedID($event);
+ }
+
/**
* Allows to set selected theme as primary
*
* @param kEvent $event
*/
function OnSetPrimary(&$event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
return;
}
$ids = $this->StoreSelectedIDs($event);
if ($ids) {
$id = array_shift($ids);
$this->setPrimary($id);
}
$this->clearSelectedIDs($event);
}
function setPrimary($id)
{
$id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
$table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
$sql = 'UPDATE '.$table_name.'
SET IsPrimary = 0';
$this->Conn->Query($sql);
$sql = 'UPDATE '.$table_name.'
SET IsPrimary = 1
WHERE '.$id_field.' = '.$id;
$this->Conn->Query($sql);
}
/**
* [HOOK] Compile stylesheet file based on theme definitions
*
* @param kEvent $event
*/
function OnCompileStylesheet(&$event)
{
$object =& $event->getObject( Array('skip_autoload' => true) );
$object->SwitchToLive();
$ids = $event->MasterEvent->getEventParam('ids');
if (!is_array($ids)) $ids = explode(',', $ids);
if(!$ids) return false;
foreach($ids as $id)
{
$object->Load($id);
$this->Compile($object);
}
}
function Compile(&$object)
{
$ret = $object->GetDBField('CSS');
$options = $object->GetDBField('Options');
$options = unserialize($options);
$options['base_url'] = array('Value'=>rtrim($this->Application->BaseURL(), '/'));
foreach ($options as $key => $row) {
$ret = str_replace('@@'.$key.'@@', $row['Value'], $ret);
}
$compile_ts = adodb_mktime();
$css_path = (defined('WRITEABLE') ? WRITEABLE : FULL_PATH.'/kernel').'/user_files/';
$css_file = $css_path.'admin-'.mb_strtolower($object->GetDBField('Name')).'-'.$compile_ts.'.css';
$fp = fopen($css_file,'w');
if($fp)
{
$prev_css = $css_path.'admin-'.mb_strtolower($object->GetDBField('Name')).'-'.$object->GetDBField('LastCompiled').'.css';
if( file_exists($prev_css) ) unlink($prev_css);
fwrite($fp, $ret);
fclose($fp);
$sql = 'UPDATE '.$object->TableName.' SET LastCompiled = '.$compile_ts.' WHERE '.$object->IDField.' = '.$object->GetID();
$this->Conn->Query($sql);
}
}
}
\ No newline at end of file
Property changes on: branches/RC/core/units/skins/skin_eh.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2.4.3
\ No newline at end of property
+1.2.4.4
\ No newline at end of property
Index: branches/RC/core/units/admin/admin_tag_processor.php
===================================================================
--- branches/RC/core/units/admin/admin_tag_processor.php (revision 11720)
+++ branches/RC/core/units/admin/admin_tag_processor.php (revision 11721)
@@ -1,1128 +1,1128 @@
<?php
class AdminTagProcessor extends kDBTagProcessor {
function SetConst($params)
{
$name = $this->SelectParam($params, 'name,const');
safeDefine($name, $params['value']);
}
/**
* Allows to execute js script after the page is fully loaded
*
* @param Array $params
* @return string
*/
function AfterScript($params)
{
$after_script = $this->Application->GetVar('after_script');
if ($after_script) {
return '<script type="text/javascript">'.$after_script.'</script>';
}
return '';
}
/**
* Returns section title with #section# keyword replaced with current section
*
* @param Array $params
* @return string
*/
function GetSectionTitle($params)
{
if (array_key_exists('default', $params)) {
return $params['default'];
}
return $this->Application->Phrase( replaceModuleSection($params['phrase']) );
}
/**
* Returns section icon with #section# keyword replaced with current section
*
* @param Array $params
* @return string
*/
function GetSectionIcon($params)
{
return replaceModuleSection($params['icon']);
}
/**
* Save return script in cases, when old sections are opened from new sections
*
* @param Array $params
*/
function SaveReturnScript($params)
{
// admin/save_redirect.php?do=
$m =& $this->Application->recallObject('m_TagProcessor');
$url = str_replace($this->Application->BaseURL(), '', $m->Link($params) );
$url = explode('?', $url, 2);
$url = 'save_redirect.php?'.$url[1].'&do='.$url[0];
$this->Application->StoreVar('ReturnScript', $url);
}
/**
* Returns version of module by name
*
* @param Array $params
* @return string
*/
function ModuleVersion($params)
{
return $this->Application->findModule('Name', $params['module'], 'Version');
}
/**
* Used in table form section drawing
*
* @param Array $params
* @return string
*/
function DrawTree($params)
{
static $deep_level = 0;
// when processings, then sort children by priority (key of children array)
$ret = '';
$section_name = $params['section_name'];
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($section_name);
$params['children_count'] = isset($section_data['children']) ? count($section_data['children']) : 0;
$params['deep_level'] = $deep_level++;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$ret .= $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
if (!isset($section_data['children'])) {
return $ret;
}
$debug_mode = $this->Application->isDebugMode();
$super_admin_mode = $this->Application->RecallVar('super_admin');
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $section_name) {
$section_data =& $sections_helper->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = $show_mode == smNORMAL || ((($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($super_admin_mode || $debug_mode));
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $debug_mode;
}
if (!$show_section) {
continue;
}
}
$params['section_name'] = $section_name;
$ret .= $this->DrawTree($params);
$deep_level--;
}
return $ret;
}
function SectionInfo($params)
{
$section = $params['section'];
if ($section == '#session#') {
$section = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section);
if (!$section_data) {
trigger_error('Use of undefined section "<strong>' . $section . '</strong>" in "<strong>' . __METHOD__ . '</strong>"', E_USER_ERROR);
return '';
}
if (isset($params['parent']) && $params['parent']) {
do {
$section_data =& $sections_helper->getSectionData($section_data['parent']);
} while (isset($section_data['use_parent_header']) && $section_data['use_parent_header']);
}
$info = $params['info'];
switch ($info) {
case 'module_path':
if (isset($params['module']) && $params['module']) {
$module = $params['module'];
}
elseif (isset($section_data['icon_module'])) {
$module = $section_data['icon_module'];
}
else {
$module = '#session#';
}
$res = $this->ModulePath(array('module' => $module));
break;
case 'perm_section':
$res = $sections_helper->getPermSection($section);
break;
default:
$res = $section_data[$info];
}
if ($info == 'label' || isset($params['as_label'])) {
$res = $this->Application->Phrase($res);
}
return $res;
}
function PrintSection($params)
{
$section_name = $params['section_name'];
if ($section_name == '#session#') {
$section_name = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
if (isset($params['use_first_child']) && $params['use_first_child']) {
$section_name = $sections_helper->getFirstChild($section_name, true);
}
$section_data =& $sections_helper->getSectionData($section_name);
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
$params['section_name'] = $section_name;
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$ret = $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
return $ret;
}
/**
* Used in XML drawing for tree
*
* @param Array $params
* @return string
*/
function PrintSections($params)
{
// when processings, then sort children by priority (key of children array)
$ret = '';
$section_name = $params['section_name'];
if ($section_name == '#session#') {
$section_name = $this->Application->RecallVar('section');
}
$sections_helper =& $this->Application->recallObject('SectionsHelper');
/* @var $sections_helper kSectionsHelper */
$section_data =& $sections_helper->getSectionData($section_name);
$params['name'] = $this->SelectParam($params, 'name,render_as,block');
if (!isset($section_data['children'])) {
return '';
}
$debug_mode = $this->Application->isDebugMode();
$super_admin_mode = $this->Application->RecallVar('super_admin');
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $section_name) {
$params['section_name'] = $section_name;
$section_data =& $sections_helper->getSectionData($section_name);
if (isset($section_data['show_mode']) && is_numeric($section_data['show_mode'])) {
$show_mode = $section_data['show_mode'];
// if super admin section -> show in super admin mode & debug mode
$show_section = $show_mode == smNORMAL || ((($show_mode & smSUPER_ADMIN) == smSUPER_ADMIN) && ($super_admin_mode || $debug_mode));
if (!$show_section) {
// if section is in debug mode only && debug mode -> show
$show_section = (($show_mode & smDEBUG) == smDEBUG) && $debug_mode;
}
if (!$show_section) {
continue;
}
}
if (isset($section_data['tabs_only']) && $section_data['tabs_only']) {
$perm_status = false;
$folder_label = $section_data['label'];
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $priority => $section_name) {
// if only tabs in this section & none of them have permission, then skip section too
$section_name = $sections_helper->getPermSection($section_name);
$perm_status = $this->Application->CheckPermission($section_name.'.view', 1);
if ($perm_status) {
break;
}
}
if (!$perm_status) {
// no permission for all tabs -> don't display tree node either
continue;
}
$params['section_name'] = $section_name;
$section_data =& $sections_helper->getSectionData($section_name);
$section_data['label'] = $folder_label; // use folder label in tree
$section_data['is_tab'] = 1;
}
else {
$section_name = $sections_helper->getPermSection($section_name);
if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue;
}
$params['children_count'] = isset($section_data['children']) ? count($section_data['children']) : 0;
// remove template, so it doesn't appear as additional parameter in url
$template = $section_data['url']['t'];
unset($section_data['url']['t']);
$section_data['section_url'] = $this->Application->HREF($template, '', $section_data['url']);
$late_load = getArrayValue($section_data, 'late_load');
if ($late_load) {
$t = $late_load['t'];
unset($late_load['t']);
$section_data['late_load'] = $this->Application->HREF($t, '', $late_load);
$params['children_count'] = 99;
}
else {
$section_data['late_load'] = '';
}
// restore template
$section_data['url']['t'] = $template;
$ret .= $this->Application->ParseBlock( array_merge_recursive2($params, $section_data) );
$params['section_name'] = $section_name;
}
return preg_replace("/\r\n|\n/", '', $ret);
}
function ListSectionPermissions($params)
{
$section_name = isset($params['section_name']) ? $params['section_name'] : $this->Application->GetVar('section_name');
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($section_name);
$block_params = array_merge_recursive2($section_data, Array('name' => $params['render_as'], 'section_name' => $section_name));
$ret = '';
foreach ($section_data['permissions'] as $perm_name) {
if (preg_match('/^advanced:(.*)/', $perm_name) != $params['type']) continue;
$block_params['perm_name'] = $perm_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ModuleInclude($params)
{
foreach ($params as $param_name => $param_value) {
$params[$param_name] = replaceModuleSection($param_value);
}
$m =& $this->Application->recallObject('m_TagProcessor');
return $m->ModuleInclude($params);
}
function TodayDate($params)
{
return date($params['format']);
}
function TreeEditWarrning($params)
{
$ret = $this->Application->Phrase($params['label']);
$ret = str_replace(Array('&lt;', '&gt;', 'br/', 'br /', "\n", "\r"), Array('<', '>', 'br', 'br', '', ''), $ret);
if (getArrayValue($params, 'escape')) {
$ret = addslashes($ret);
}
$ret = str_replace('<br>', '\n', $ret);
return $ret;
}
/**
* Draws section tabs using block name passed
*
* @param Array $params
*/
function ListTabs($params)
{
$sections_helper =& $this->Application->recallObject('SectionsHelper');
$section_data =& $sections_helper->getSectionData($params['section_name']);
$ret = '';
$block_params = Array('name' => $params['render_as']);
ksort($section_data['children'], SORT_NUMERIC);
foreach ($section_data['children'] as $priority => $section_name) {
if (!$this->Application->CheckPermission($section_name.'.view', 1)) continue;
$tab_data =& $sections_helper->getSectionData($section_name);
$block_params['t'] = $tab_data['url']['t'];
$block_params['title'] = $tab_data['label'];
$block_params['main_prefix'] = $section_data['SectionPrefix'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Returns list of module item tabs that have view permission in current category
*
* @param Array $params
*/
function ListCatalogTabs($params)
{
$ret = '';
$special = isset($params['special']) ? $params['special'] : '';
$replace_main = isset($params['replace_m']) && $params['replace_m'];
$skip_prefixes = isset($params['skip_prefixes']) ? explode(',', $params['skip_prefixes']) : Array();
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
foreach ($this->Application->ModuleInfo as $module_name => $module_info) {
$prefix = $module_info['Var'];
if ($prefix == 'm' && $replace_main) {
$prefix = 'c';
}
if (in_array($prefix, $skip_prefixes) || !$this->Application->prefixRegistred($prefix) || !$this->Application->getUnitOption($prefix, 'CatalogItem')) {
continue;
}
$icon = $this->Application->getUnitOption($prefix, 'CatalogTabIcon');
if (strpos($icon, ':') !== false) {
list ($icon_module, $icon) = explode(':', $icon, 2);
}
else {
$icon_module = 'core';
}
$label = $this->Application->getUnitOption($prefix, $params['title_property']);
$block_params['title'] = $label;
$block_params['prefix'] = $prefix;
$block_params['icon_module'] = $icon_module;
$block_params['icon'] = $icon;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Renders inividual catalog tab based on prefix and title_property given
*
* @param Array $params
* @return string
*/
function CatalogTab($params)
{
$icon = $this->Application->getUnitOption($params['prefix'], 'CatalogTabIcon');
if (strpos($icon, ':') !== false) {
list ($icon_module, $icon) = explode(':', $icon, 2);
}
else {
$icon_module = 'core';
}
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$block_params['icon_module'] = $icon_module;
$block_params['icon'] = $icon;
$block_params['title'] = $this->Application->getUnitOption($params['prefix'], $params['title_property']);
return $this->Application->ParseBlock($block_params);
}
/**
* Allows to construct link for opening any type of catalog item selector
*
* @param Array $params
* @return string
*/
function SelectorLink($params)
{
$mode = 'catalog';
if (isset($params['mode'])) { // {catalog, advanced_view}
$mode = $params['mode'];
unset($params['mode']);
}
$params['t'] = 'catalog/item_selector/item_selector_'.$mode;
$params['m_cat_id'] = $this->Application->findModule('Name', 'Core', 'RootCat');
$default_params = Array('no_amp' => 1, 'pass' => 'all,'.$params['prefix']);
unset($params['prefix']);
$pass_through = Array();
if (isset($params['tabs_dependant'])) { // {yes, no}
$pass_through['td'] = $params['tabs_dependant'];
unset($params['tabs_dependant']);
}
if (isset($params['selection_mode'])) { // {single, multi}
$pass_through['tm'] = $params['selection_mode'];
unset($params['selection_mode']);
}
if (isset($params['tab_prefixes'])) { // {all, none, <comma separated prefix list>}
$pass_through['tp'] = $params['tab_prefixes'];
unset($params['tab_prefixes']);
}
if ($pass_through) {
// add pass_through to selector url if any
$params['pass_through'] = implode(',', array_keys($pass_through));
$params = array_merge_recursive2($params, $pass_through);
}
// user can override default parameters (except pass_through of course)
$params = array_merge_recursive2($default_params, $params);
$main_processor =& $this->Application->recallObject('m_TagProcessor');
return $main_processor->T($params);
}
function TimeFrame($params)
{
$w = adodb_date('w');
$m = adodb_date('m');
$y = adodb_date('Y');
//FirstDayOfWeek is 0 for Sunday and 1 for Monday
$fdow = $this->Application->ConfigValue('FirstDayOfWeek');
if ($fdow && $w == 0) $w = 7;
$today_start = adodb_mktime(0,0,0,adodb_date('m'),adodb_date('d'),$y);
$first_day_of_this_week = $today_start - ($w - $fdow)*86400;
$first_day_of_this_month = adodb_mktime(0,0,0,$m,1,$y);
$this_quater = ceil($m/3);
$this_quater_start = adodb_mktime(0,0,0,$this_quater*3-2,1,$y);
switch ($params['type']) {
case 'last_week_start':
$timestamp = $first_day_of_this_week - 86400*7;
break;
case 'last_week_end':
$timestamp = $first_day_of_this_week - 1;
break;
case 'last_month_start':
$timestamp = $m == 1 ? adodb_mktime(0,0,0,12,1,$y-1) : adodb_mktime(0,0,0,$m-1,1,$y);
break;
case 'last_month_end':
$timestamp = $first_day_of_this_month = adodb_mktime(0,0,0,$m,1,$y) - 1;
break;
case 'last_quater_start':
$timestamp = $this_quater == 1 ? adodb_mktime(0,0,0,10,1,$y-1) : adodb_mktime(0,0,0,($this_quater-1)*3-2,1,$y);
break;
case 'last_quater_end':
$timestamp = $this_quater_start - 1;
break;
case 'last_6_months_start':
$timestamp = $m <= 6 ? adodb_mktime(0,0,0,$m+6,1,$y-1) : adodb_mktime(0,0,0,$m-6,1,$y);
break;
case 'last_year_start':
$timestamp = adodb_mktime(0,0,0,1,1,$y-1);
break;
case 'last_year_end':
$timestamp = adodb_mktime(23,59,59,12,31,$y-1);
break;
}
if (isset($params['format'])) {
$format = $params['format'];
if(preg_match("/_regional_(.*)/", $format, $regs))
{
$lang =& $this->Application->recallObject('lang.current');
$format = $lang->GetDBField($regs[1]);
}
return adodb_date($format, $timestamp);
}
return $timestamp;
}
/**
* Redirect to cache rebuild template, when required by installator
*
* @param Array $params
*/
function CheckPermCache($params)
{
// we have separate session between install wizard and admin console, so store in cache
$sql = 'SELECT Data
FROM '.TABLE_PREFIX.'Cache
WHERE VarName = "ForcePermCacheUpdate"';
$global_mark = $this->Conn->GetOne($sql);
$local_mark = $this->Application->RecallVar('PermCache_UpdateRequired');
if ($global_mark || $local_mark) {
$this->Application->RemoveVar('PermCache_UpdateRequired');
if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) {
$updater =& $this->Application->recallObject('kPermCacheUpdater');
/* @var $updater kPermCacheUpdater */
$updater->OneStepRun();
}
else {
// update with progress bar
return true;
}
}
return false;
}
/**
* Checks if current protocol is SSL
*
* @param Array $params
* @return int
*/
function IsSSL($params)
{
return (PROTOCOL == 'https://')? 1 : 0;
}
function PrintColumns($params)
{
$picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
$picker_helper->SetGridName($this->Application->GetLinkedVar('grid_name'));
/* @var $picker_helper kColumnPickerHelper */
$main_prefix = $this->Application->RecallVar('main_prefix');
$cols = $picker_helper->LoadColumns($main_prefix);
$this->Application->Phrases->AddCachedPhrase('__FREEZER__', '-------------');
$o = '';
if (isset($params['hidden']) && $params['hidden']) {
foreach ($cols['hidden_fields'] as $col) {
$title = $this->Application->Phrase($cols['titles'][$col]);
$o .= "<option value='$col'>".$title;
}
}
else {
foreach ($cols['order'] as $col) {
if (in_array($col, $cols['hidden_fields'])) continue;
$title = $this->Application->Phrase($cols['titles'][$col]);
$o .= "<option value='$col'>".$title;
}
}
return $o;
}
/**
* Allows to set popup size (key - current template name)
*
* @param Array $params
*/
function SetPopupSize($params)
{
$width = $params['width'];
$height = $params['height'];
if ($this->Application->GetVar('ajax') == 'yes') {
// during AJAX request just output size
die($width.'x'.$height);
}
if (!$this->UsePopups($params)) {
return ;
}
$t = $this->Application->GetVar('t');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'PopupSizes
WHERE TemplateName = '.$this->Conn->qstr($t);
$popup_info = $this->Conn->GetRow($sql);
if (!$popup_info) {
// create new popup size record
$fields_hash = Array (
'TemplateName' => $t,
'PopupWidth' => $width,
'PopupHeight' => $height,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX.'PopupSizes');
}
elseif ($popup_info['PopupWidth'] != $width || $popup_info['PopupHeight'] != $height) {
// popup found and size in tag differs from one in db -> update in db
$fields_hash = Array (
'PopupWidth' => $width,
'PopupHeight' => $height,
);
$this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'PopupSizes', 'PopupId = '.$popup_info['PopupId']);
}
}
/**
* Returns popup size (by template), if not cached, then parse template to get value
*
* @param Array $params
* @return string
*/
function GetPopupSize($params)
{
$t = $this->Application->GetVar('template_name');
$sql = 'SELECT *
FROM '.TABLE_PREFIX.'PopupSizes
WHERE TemplateName = '.$this->Conn->qstr($t);
$popup_info = $this->Conn->GetRow($sql);
if (!$popup_info) {
$this->Application->InitParser();
$this->Application->ParseBlock(array('name' => $t)); // dies when SetPopupSize tag found & in ajax requrest
return '750x400'; // tag SetPopupSize not found in template -> use default size
}
return $popup_info['PopupWidth'].'x'.$popup_info['PopupHeight'];
}
function UsePopups($params)
{
return (int)$this->Application->ConfigValue('UsePopups') || $this->Application->GetVar('_force_popup');
}
function UseToolbarLabels($params)
{
return (int)$this->Application->ConfigValue('UseToolbarLabels');
}
/**
* Checks if debug mode enabled (optionally) and specified constant is on
*
* @param Array $params
* @return bool
*/
function ConstOn($params)
{
$constant_name = $this->SelectParam($params, 'name,const');
$debug_mode = isset($params['debug_mode']) && $params['debug_mode'] ? $this->Application->isDebugMode() : true;
return $debug_mode && constOn($constant_name);
}
/**
* Builds link to last template in main frame of admin
*
* @param Array $params
* @return string
*/
function MainFrameLink($params)
{
$persistent = isset($params['persistent']) && $params['persistent'];
if ($persistent && $this->Application->ConfigValue('RememberLastAdminTemplate')) {
// check last_template in persistent session
$last_template = $this->Application->RecallPersistentVar('last_template_popup');
}
else {
// check last_template in session
$last_template = $this->Application->RecallVar('last_template_popup'); // because of m_opener=s there
}
if (!$last_template) {
$params['persistent'] = 1;
return $persistent ? false : $this->MainFrameLink($params);
}
list($index_file, $env) = explode('|', $last_template);
$vars = $this->Application->HttpQuery->processQueryString($env, 'pass');
$recursion_templates = Array ('login', 'index', 'no_permission');
if (isset($vars['admin']) && $vars['admin'] == 1) {
// index template doesn't begin recursion on front-end (in admin frame)
$vars['m_theme'] = '';
if (isset($params['m_opener']) && $params['m_opener'] == 'r') {
// front-end link for highlighting purposes
$vars['t'] = 'index';
$vars['m_cat_id'] = $this->Application->findModule('Name', 'Core', 'RootCat');
}
unset($recursion_templates[ array_search('index', $recursion_templates)]);
}
if (in_array($vars['t'], $recursion_templates)) {
// prevents redirect recursion OR old in-portal pages
$params['persistent'] = 1;
return $persistent ? false : $this->MainFrameLink($params);
}
$vars = array_merge_recursive2($vars, $params);
$t = $vars['t'];
unset($vars['t'], $vars['persistent']);
return $this->Application->HREF($t, '', $vars, $index_file);
}
/**
* Returns menu frame width or 200 in case, when invalid width specified in config
*
* @param Array $params
* @return string
*/
function MenuFrameWidth($params)
{
$width = (int)$this->Application->ConfigValue('MenuFrameWidth');
return $width > 0 ? $width : 200;
}
function AdminSkin($params)
{
static $style;
if (!isset($style)) {
$style = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'Skins WHERE IsPrimary = 1');
}
- $css_path = (defined('WRITEABLE') ? WRITEABLE : FULL_PATH.'/kernel') . '/user_files';
- $css_url = $this->Application->BaseURL(defined('WRITEBALE_BASE') ? WRITEBALE_BASE : '/kernel') . 'user_files/';
+ $css_path = (defined('WRITEABLE') ? WRITEABLE : FULL_PATH. DIRECTORY_SEPARATOR . 'kernel') . DIRECTORY_SEPARATOR . 'user_files';
+ $css_url = $this->Application->BaseURL(defined('WRITEBALE_BASE') ? str_replace(DIRECTORY_SEPARATOR, '/', WRITEBALE_BASE) : '/kernel') . 'user_files/';
$type = array_key_exists('type', $params) ? $params['type'] : false;
if ($type == 'logo') {
$type = 'Logo';
}
if ($type == 'Logo' || $type == 'LogoBottom' || $type == 'LogoLogin') {
return $style[$type] ? $css_url.$style[$type] : '';
}
$last_compiled = $style['LastCompiled'];
$style_name = mb_strtolower( $style['Name'] );
if( file_exists($css_path.'/'.'admin-'.$style_name.'-'.$last_compiled.'.css') )
{
$ret = $css_url.'admin-'.$style_name.'-'.$last_compiled.'.css';
}
else
{
// search for previously compiled stylesheet
$last_compiled = 0;
if( $dh = opendir($css_path) )
{
while( ($file = readdir($dh)) !== false )
{
if( preg_match('/admin-(.*)-([\d]+).css/', $file, $rets) )
{
if( $rets[1] == $style_name && $rets[2] > $last_compiled ) $last_compiled = $rets[2];
}
}
closedir($dh);
}
if ($last_compiled) {
// found
$ret = $css_url.'admin-'.$style_name.'-'.$last_compiled.'.css';
}
else {
// not found (try to compile on the fly)
$object =& $this->Application->recallObject('skin.-item', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$skin_eh =& $this->Application->recallObject('skin_EventHandler');
/* @var $skin_eh SkinEventHandler */
$object->Load(1, 'IsPrimary');
$skin_eh->Compile($object);
$ret = $css_url.'admin-'.$style_name.'-'.adodb_mktime().'.css';
}
}
if (isset($params['file_only'])) return $ret;
return '<link rel="stylesheet" rev="stylesheet" href="'.$ret.'" type="text/css" media="screen" />';
}
function PrintCompileErrors($params)
{
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$errors = $this->Application->RecallVar('compile_errors');
if (!$errors) {
return ;
}
$ret = '';
$errors = unserialize($errors);
foreach ($errors as $an_error) {
$block_params['file'] = str_replace(FULL_PATH, '', $an_error['file']);
$block_params['line'] = $an_error['line'];
$block_params['message'] = $an_error['msg'];
$ret .= $this->Application->ParseBlock($block_params);
}
$this->Application->RemoveVar('compile_errors');
return $ret;
}
function CompileErrorCount($params)
{
$errors = $this->Application->RecallVar('compile_errors');
if (!$errors) {
return 0;
}
return count( unserialize($errors) );
}
function ExportData($params)
{
$export_helper =& $this->Application->recallObject('CSVHelper');
/* @var $export_helper kCSVHelper */
$result = $export_helper->ExportData( $this->SelectParam($params, 'var,name,field') );
return ($result === false) ? '' : $result;
}
function ImportData($params)
{
$import_helper =& $this->Application->recallObject('CSVHelper');
/* @var $import_helper kCSVHelper */
$result = $import_helper->ImportData( $this->SelectParam($params, 'var,name,field') );
return ($result === false) ? '' : $result;
}
function PrintCSVNotImportedLines($params)
{
$import_helper =& $this->Application->recallObject('CSVHelper');
/* @var $import_helper kCSVHelper */
return $import_helper->GetNotImportedLines();
}
/**
* Returns input field name to
* be placed on form (for correct
* event processing)
*
* @param Array $params
* @return string
* @access public
*/
function InputName($params)
{
list($id, $field) = $this->prepareInputName($params);
$ret = $this->getPrefixSpecial().'[0]['.$field.']'; // 0 always, as has no idfield
if( getArrayValue($params, 'as_preg') ) $ret = preg_quote($ret, '/');
return $ret;
}
/**
* Returns list of all backup file dates formatted
* in passed block
*
* @param Array $params
* @return string
* @access public
*/
function PrintBackupDates($params)
{
$datearray = $this->getDirList($this->Application->ConfigValue('Backup_Path'));
$ret = '';
foreach($datearray as $key => $value)
{
$params['backuptimestamp'] = $value['filedate'];
$params['backuptime'] = date('F j, Y, g:i a', $value['filedate']);
$params['backupsize'] = round($value['filesize']/1024/1024, 2); // MBytes
$ret .= $this->Application->ParseBlock($params);
}
return $ret;
}
function getDirList ($dirName)
{
$fileinfo = array();
$d = dir($dirName);
while($entry = $d->read())
{
if ($entry != "." && $entry != "..")
{
if (!is_dir($dirName."/".$entry) && eregi("dump",$entry))
{
$fileinfo[]= Array('filedate' => $this->chopchop($entry),
'filesize' => filesize($dirName. '/'. $entry)
);
}
}
}
$d->close();
rsort($fileinfo);
return $fileinfo;
}
function chopchop ($filename)
{
$p = pathinfo($filename);
$ext = '.'.$p["extension"];
$filename;
$filename= ereg_replace("dump","",$filename);
$filename= ereg_replace($ext,"",$filename);
return $filename;
}
function PrintPHPinfo($params)
{
$php_info = '';
ob_start();
phpinfo();
$php_info .= ob_get_contents();
ob_end_clean();
$php_info = str_replace(" width=\"600\"", " width=\"100%\" align=\"center\"", $php_info);
$php_info = str_replace("</body>", "", $php_info);
$php_info = str_replace("<body>", "", $php_info);
$php_info = str_replace("</html>", "", $php_info);
$php_info = str_replace("<html>", "", $php_info);
$php_info = str_replace("</head>", "", $php_info);
$php_info = str_replace("<head>", "", $php_info);
$offset = strpos($php_info, "<table");
$php_info = substr($php_info, $offset);
$php_info = '<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
pre {margin: 0px; font-family: monospace;}
a:link {color: #000099; text-decoration: none; background-color: #ffffff;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse;}
.center {text-align: center;}
.center table { margin-left: auto; margin-right: auto; text-align: left;}
.center th { text-align: center !important; }
td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}
h1 {font-size: 150%;}
h2 {font-size: 125%;}
.p {text-align: left;}
.e {background-color: #ccccff; font-weight: bold; color: #000000;}
.h {background-color: #9999cc; font-weight: bold; color: #000000;}
.v {background-color: #cccccc; color: #000000;}
i {color: #666666; background-color: #cccccc;}
hr {width: 600px; background-color: #cccccc; border: 0px; height: 1px; color: #000000;}
</style>'.$php_info;
return $php_info;
}
function PrintSqlCols($params)
{
$a_data = unserialize($this->Application->GetVar('sql_rows'));
$ret = '';
$block = $params['render_as'];
foreach ($a_data AS $a_row)
{
foreach ($a_row AS $col => $value)
{
$ret .= $this->Application->ParseBlock(Array('name'=>$block, 'value'=>$col));
}
break;
}
return $ret;
}
function PrintSqlRows($params)
{
$a_data = unserialize($this->Application->GetVar('sql_rows'));
$ret = '';
$block = $params['render_as'];
foreach ($a_data AS $a_row)
{
$cells = '';
foreach ($a_row AS $col => $value)
{
$cells .= '<td>'.$value.'</td>';
}
$ret .= $this->Application->ParseBlock(Array('name'=>$block, 'cells'=>$cells));
}
return $ret;
}
/**
* Prints available and enabled import sources using given block
*
* @param Array $params
* @return string
*/
function PrintImportSources($params)
{
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'ImportScripts
WHERE (Status = ' . STATUS_ACTIVE . ') AND (Type = "CSV")';
$import_sources = $this->Conn->Query($sql);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$ret = '';
foreach ($import_sources as $import_source) {
$block_params['script_id'] = $import_source['ImportId'];
$block_params['script_module'] = $import_source['Module'];
$block_params['script_name'] = $import_source['Name'];
$block_params['script_prefix'] = $import_source['Prefix'];
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Checks, that new window should be opened in "incs/close_popup" template instead of refreshing parent window
*
* @param Array $params
* @return bool
*/
function OpenNewWindow($params)
{
if (!$this->UsePopups($params)) {
return false;
}
$diff = array_key_exists('diff', $params) ? $params['diff'] : 0;
$wid = $this->Application->GetVar('m_wid');
$stack_name = rtrim('opener_stack_' . $wid, '_');
$opener_stack = $this->Application->RecallVar($stack_name);
$opener_stack = $opener_stack ? unserialize($opener_stack) : Array ();
return count($opener_stack) >= 2 - $diff;
}
}
?>
\ No newline at end of file
Property changes on: branches/RC/core/units/admin/admin_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.43.2.36
\ No newline at end of property
+1.43.2.37
\ 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 11720)
+++ branches/RC/core/units/general/helpers/image_helper.php (revision 11721)
@@ -1,396 +1,396 @@
<?php
class ImageHelper extends kHelper {
/**
* Parses format string into array
*
* @param string $format sample format: "resize:300x500;wm:inc/wm.png|c|-20"
* @return Array sample result: Array('max_width' => 300, 'max_height' => 500, 'wm_filename' => 'inc/wm.png', 'h_margin' => 'c', 'v_margin' => -20)
*/
function parseFormat($format)
{
$res = Array ();
$format_parts = explode(';', $format);
foreach ($format_parts as $format_part) {
if (preg_match('/resize:(\d*)x(\d*)/', $format_part, $regs)) {
$res['max_width'] = $regs[1];
$res['max_height'] = $regs[2];
}
elseif (preg_match('/wm:([^\|]*)\|([^\|]*)\|([^\|]*)/', $format_part, $regs)) {
$res['wm_filename'] = FULL_PATH.THEMES_PATH.'/'.$regs[1];
$res['h_margin'] = $regs[2];
$res['v_margin'] = $regs[3];
}
elseif ($format_part == 'img_size' || $format_part == 'img_sizes') {
$res['image_size'] = true;
}
}
return $res;
}
/**
* 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 = null)
{
$image_size = false;
if(isset($max_height)) {
$params['max_height'] = $max_height;
$params['max_width'] = $max_width;
}
else {
$params = $this->parseFormat($max_width);
if (array_key_exists('image_size', $params)) {
// image_size param shouldn't affect resized file name (crc part)
$image_size = $params['image_size'];
unset($params['image_size']);
}
}
if ($params['max_width'] > 0 || $params['max_height'] > 0) {
list ($params['max_width'], $params['max_height'], $needs_resize) = $this->GetImageDimensions($src_image, $params['max_width'], $params['max_height']);
$src_path = dirname($src_image);
if ($needs_resize || array_key_exists('wm_filename', $params) && $params['wm_filename']) {
// resize required OR watermarking required -> change resulting image name !
- $dst_image = preg_replace('/^'.preg_quote($src_path, '/').'(.*)\.(.*)$/', $src_path.'/resized\\1_'.crc32(serialize($params)).'.\\2', $src_image);
+ $dst_image = preg_replace('/^'.preg_quote($src_path, '/').'(.*)\.(.*)$/', $src_path . DIRECTORY_SEPARATOR . 'resized\\1_' . crc32(serialize($params)) . '.\\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
$params['dst_image'] = $dst_image;
$image_resized = $this->ScaleImage($src_image, $params);
if (!$image_resized) {
// resize failed, because of server error
$dst_image = $src_image;
}
}
// resize/watermarking ok
$src_image = $dst_image;
}
}
if ($image_size) {
// return only image size (resized or not)
$image_info = $this->getImageInfo($src_image);
return $image_info ? $image_info[3] : '';
}
$base_url = rtrim($this->Application->BaseURL(), '/');
- return preg_replace('/^'.preg_quote(FULL_PATH, '/').'(.*)/', $base_url.'\\1', $src_image);
+ return str_replace(DIRECTORY_SEPARATOR, '/', 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, $params)
{
$image_info = $this->getImageInfo($src_image);
if (!$image_info) {
return false;
}
/* list ($params['max_width'], $params['max_height'], $resized) = $this->GetImageDimensions($src_image, $params['max_width'], $params['max_height']);
if (!$resized) {
// image dimensions are smaller or equals to required dimensions
return false;
}*/
if (!$this->Application->ConfigValue('ForceImageMagickResize') && 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($params['max_width'], $params['max_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, $params['max_width'], $params['max_height'], $image_info[0], $image_info[1]);
if(array_key_exists('wm_filename', $params) && $params['wm_filename'] && file_exists($params['wm_filename']))
{
$logo_img = imagecreatefrompng($params['wm_filename']);
list($logo_width, $logo_height) = getimagesize($params['wm_filename']);
//if(($params['max_width'] > $logo_width * 2) && ($params['max_height'] > $logo_height * 2))
//{
imagealphablending($dst_image_rs, true);
//imagecopy($dst_image_rs, $logo_img, $params['max_width'] - $logo_width - $right_margin, $params['max_height'] - $logo_height - $bottom_margin, 0, 0, $logo_width, $logo_height);
if ($params['h_margin'] == 'c') {
$x_position = round($params['max_width']/2 - $logo_width/2);
}
elseif ($params['h_margin'] >= 0) {
$x_position = $params['h_margin'];
}
else {
$x_position = $params['max_width'] - (-$params['h_margin'] + $logo_width);
}
if ($params['v_margin'] == 'c') {
$y_position = round($params['max_height']/2 - $logo_height/2);
}
elseif ($params['v_margin'] >= 0) {
$y_position = $params['v_margin'];
}
else {
$y_position = $params['max_height'] - (-$params['v_margin'] + $logo_height);
}
imagecopy($dst_image_rs, $logo_img, $x_position, $y_position, 0, 0, $logo_width, $logo_height);
//}
}
return @$write_function($dst_image_rs, $params['dst_image'], 100);
}
}
else {
// try to resize using ImageMagick
exec('/usr/bin/convert '.$src_image.' -resize '.$params['max_width'].'x'.$params['max_height'].' '.$params['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];
}
/**
* Puts existing item images (from subitem) to virtual fields (in main item)
*
* @param kCatDBItem $object
*/
function LoadItemImages(&$object)
{
if (!$this->Application->prefixRegistred($object->Prefix.'-img')) {
return ;
}
$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
if (array_key_exists('PrimaryImage', $object->Fields)) {
$object->SetDBField('PrimaryImage', $image_path);
$object->SetOriginalField('PrimaryImage', $image_path);
$object->Fields['PrimaryImage']['original_field'] = $item_image['Name'];
}
continue;
}
if (array_key_exists('Image'.$image_counter, $object->Fields)) {
$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)
{
if (!$this->Application->prefixRegistred($object->Prefix.'-img')) {
return ;
}
$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++;
}
}
}
?>
\ 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.13
\ No newline at end of property
+1.6.2.14
\ No newline at end of property

Event Timeline