Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Mon, Aug 11, 8:11 AM

in-portal

Index: branches/5.3.x/core/units/helpers/upload_helper.php
===================================================================
--- branches/5.3.x/core/units/helpers/upload_helper.php (revision 16390)
+++ branches/5.3.x/core/units/helpers/upload_helper.php (revision 16391)
@@ -1,332 +1,332 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2012 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
class kUploadHelper extends kHelper
{
/**
* Creates kUploadHelper instance.
*/
public function __construct()
{
parent::__construct();
// 5 minutes execution time
@set_time_limit(5 * 60);
}
/**
* Handles the upload.
*
* @param kEvent $event Event.
*
* @return string
* @throws kUploaderException When upload could not be handled properly.
*/
public function handle(kEvent $event)
{
$this->disableBrowserCache();
// Uncomment this one to fake upload time
// sleep(5);
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 these variables also are not submitted.
throw new kUploaderException('File size exceeds allowed limit.', 413);
}
if ( !$this->checkPermissions($event) ) {
// 403 Forbidden
throw new kUploaderException('You don\'t have permissions to upload.', 403);
}
$value = $this->Application->GetVar('file');
if ( !$value || ($value['error'] != UPLOAD_ERR_OK) ) {
// 413 Request Entity Too Large (file uploads disabled OR uploaded file was
// too large for web server to accept, see "upload_max_filesize" in php.ini)
throw new kUploaderException('File size exceeds allowed limit.', 413);
}
- $value = $this->Application->HttpQuery->unescapeRequestVariable($value);
+ $value = $this->Application->unescapeRequestVariable($value);
$tmp_path = WRITEABLE . '/tmp/';
$filename = $this->getUploadedFilename() . '.tmp';
$id = $this->Application->GetVar('id');
if ( $id ) {
$filename = $id . '_' . $filename;
}
if ( !is_writable($tmp_path) ) {
// 500 Internal Server Error
// check both temp and live upload directory
throw new kUploaderException('Write permissions not set on the server, please contact server administrator.', 500);
}
/** @var FileHelper $file_helper */
$file_helper = $this->Application->recallObject('FileHelper');
$filename = $file_helper->ensureUniqueFilename($tmp_path, $filename);
$storage_format = $this->getStorageFormat($this->Application->GetVar('field'), $event);
if ( $storage_format ) {
$image_helper = $this->Application->recallObject('ImageHelper');
/* @var $image_helper ImageHelper */
$this->moveUploadedFile($value['tmp_name'] . '.jpg'); // add extension, so ResizeImage can work
$url = $image_helper->ResizeImage($value['tmp_name'] . '.jpg', $storage_format);
$tmp_name = preg_replace('/^' . preg_quote($this->Application->BaseURL(), '/') . '/', '/', $url);
rename($tmp_name, $tmp_path . $filename);
}
else {
$this->moveUploadedFile($tmp_path . $filename);
}
$this->deleteTempFiles($tmp_path);
if ( file_exists($tmp_path . 'resized/') ) {
$this->deleteTempFiles($tmp_path . 'resized/');
}
return preg_replace('/^' . preg_quote($id, '/') . '_/', '', $filename);
}
/**
* Sends headers to ensure, that response is never cached.
*
* @return void
*/
protected function disableBrowserCache()
{
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
}
/**
* Checks, that flash uploader is allowed to perform upload
*
* @param kEvent $event
* @return bool
*/
protected function checkPermissions(kEvent $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_session = $this->Application->recallObject('Session.admin');
/* @var $admin_session Session */
if ( $admin_session->RecallVar('user_id') == USER_ROOT ) {
return true;
}
// copy some data from given session to current session
$backup_user_id = $this->Application->RecallVar('user_id');
$this->Application->StoreVar('user_id', $admin_session->RecallVar('user_id'));
$backup_user_groups = $this->Application->RecallVar('UserGroups');
$this->Application->StoreVar('UserGroups', $admin_session->RecallVar('UserGroups'));
// check permissions using event, that have "add|edit" rule
$check_event = new kEvent($event->getPrefixSpecial() . ':OnProcessSelected');
$check_event->setEventParam('top_prefix', $this->Application->GetTopmostPrefix($event->Prefix, true));
/** @var kEventHandler $event_handler */
$event_handler = $this->Application->recallObject($event->Prefix . '_EventHandler');
$allowed_to_upload = $event_handler->CheckPermission($check_event);
// restore changed data, so nothing gets saved to database
$this->Application->StoreVar('user_id', $backup_user_id);
$this->Application->StoreVar('UserGroups', $backup_user_groups);
return $allowed_to_upload;
}
/**
* Returns uploaded filename.
*
* @return string
*/
protected function getUploadedFilename()
{
if ( isset($_REQUEST['name']) ) {
$file_name = $_REQUEST['name'];
}
elseif ( !empty($_FILES) ) {
$file_name = $_FILES['file']['name'];
}
else {
$file_name = uniqid('file_');
}
return $file_name;
}
/**
* Gets storage format for a given field.
*
* @param string $field_name
* @param kEvent $event
* @return bool
*/
protected function getStorageFormat($field_name, kEvent $event)
{
$config = $event->getUnitConfig();
$field_options = $config->getFieldByName($field_name);
if ( !$field_options ) {
$field_options = $config->getVirtualFieldByName($field_name);
}
return isset($field_options['storage_format']) ? $field_options['storage_format'] : false;
}
/**
* Moves uploaded file to given location.
*
* @param string $file_path File path.
*
* @return void
* @throws kUploaderException When upload could not be handled properly.
*/
protected function moveUploadedFile($file_path)
{
// Chunking might be enabled
$chunk = (int)$this->Application->GetVar('chunk', 0);
$chunks = (int)$this->Application->GetVar('chunks', 0);
// Open temp file
if ( !$out = @fopen("{$file_path}.part", $chunks ? 'ab' : 'wb') ) {
throw new kUploaderException('Failed to open output stream.', 102);
}
if ( !empty($_FILES) ) {
if ( $_FILES['file']['error'] || !is_uploaded_file($_FILES['file']['tmp_name']) ) {
throw new kUploaderException('Failed to move uploaded file.', 103);
}
// Read binary input stream and append it to temp file
if ( !$in = @fopen($_FILES['file']['tmp_name'], 'rb') ) {
throw new kUploaderException('Failed to open input stream.', 101);
}
}
else {
if ( !$in = @fopen('php://input', 'rb') ) {
throw new kUploaderException('Failed to open input stream.', 101);
}
}
while ( $buff = fread($in, 4096) ) {
fwrite($out, $buff);
}
@fclose($out);
@fclose($in);
// Check if file has been uploaded
if ( !$chunks || $chunk == $chunks - 1 ) {
// Strip the temp .part suffix off
rename("{$file_path}.part", $file_path);
}
}
/**
* Delete temporary files, that won't be used for sure
*
* @param string $path
* @return void
*/
protected function deleteTempFiles($path)
{
$files = glob($path . '*.*');
$max_file_date = strtotime('-1 day');
foreach ($files as $file) {
if (filemtime($file) < $max_file_date) {
unlink($file);
}
}
}
/**
* Prepares object for operations with file on given field.
*
* @param kEvent $event Event.
* @param string $field Field.
*
* @return kDBItem
*/
public function prepareUploadedFile(kEvent $event, $field)
{
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
$filename = $this->getSafeFilename();
if ( !$filename ) {
$object->SetDBField($field, '');
return $object;
}
// set current uploaded file
if ( $this->Application->GetVar('tmp') ) {
$options = $object->GetFieldOptions($field);
$options['upload_dir'] = WRITEBALE_BASE . '/tmp/';
unset($options['include_path']);
$object->SetFieldOptions($field, $options);
$filename = $this->Application->GetVar('id') . '_' . $filename;
}
$object->SetDBField($field, $filename);
return $object;
}
/**
* Returns safe version of filename specified in url
*
* @return bool|string
* @access protected
*/
protected function getSafeFilename()
{
$filename = $this->Application->GetVar('file');
$filename = $this->Application->unescapeRequestVariable($filename);
if ( (strpos($filename, '../') !== false) || (trim($filename) !== $filename) ) {
// when relative paths or special chars are found template names from url, then it's hacking attempt
return false;
}
return $filename;
}
}
class kUploaderException extends Exception
{
}
Index: branches/5.3.x/core/units/helpers/country_states_helper.php
===================================================================
--- branches/5.3.x/core/units/helpers/country_states_helper.php (revision 16390)
+++ branches/5.3.x/core/units/helpers/country_states_helper.php (revision 16391)
@@ -1,245 +1,245 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kCountryStatesHelper extends kHelper
{
/**
* ID of current language.
*
* @var integer
*/
protected $currentLanguage;
/**
* ID of primary language.
*
* @var integer
*/
protected $primaryLanguage;
/**
* Populates language ids that are used.
*/
public function __construct()
{
parent::__construct();
// Don't use GetVar('m_lang') since it's always equals to default language on editing form in admin.
$this->currentLanguage = $this->Application->Phrases->LanguageId;
$this->primaryLanguage = $this->Application->GetDefaultLanguageId();
}
/**
* Returns countries, that have states
*
* @return Array
*/
function getCountriesWithStates()
{
static $cache = null;
if ( !isset($cache) ) {
$table_name = $this->Application->getUnitConfig('country-state')->getTableName();
$sql = 'SELECT DISTINCT cname.IsoCode, cid.StateCountryId
FROM ' . $table_name . ' cid
JOIN ' . $table_name . ' cname ON cname.CountryStateId = cid.StateCountryId
WHERE cid.StateCountryId IS NOT NULL';
$cache = $this->Conn->GetCol($sql, 'StateCountryId');
}
return $cache;
}
/**
* Checks, that country with given 3symbol ISO code has states
*
* @param string $country_code
* @return bool
*/
function CountryHasStates($country_code)
{
return $country_code ? in_array($country_code, $this->getCountriesWithStates()) : false;
}
/**
* Prepares states dropdown based on country selected
*
* @param kEvent $event
* @param string $state_field
* @param string $country_field
*/
function PopulateStates($event, $state_field, $country_field)
{
$object = $event->getObject();
/* @var $object kDBItem */
$country_iso = $object->GetDBField($country_field);
if ( !$country_iso ) {
- return;
- }
+ return;
+ }
$field_options = $object->GetFieldOptions($state_field);
$field_options['options'] = $this->getStates($country_iso);
$object->SetFieldOptions($state_field, $field_options, $object->isVirtualField($state_field));
}
/**
* Returns list of given country states
*
* @param string $country_iso
* @return Array
*/
public function getStates($country_iso)
{
$country_id = $this->getCountryStateId($country_iso, DESTINATION_TYPE_COUNTRY);
if ( !$country_id ) {
return Array ();
}
$cache_key = 'country_states[%CountryStateSerial%]';
$cache_key .= ':PL=' . $this->primaryLanguage . ':CL=' . $this->currentLanguage . ':ISO=' . $country_iso;
$states = $this->Application->getCache($cache_key);
if ( $states === false ) {
$sql = 'SELECT IF(l' . $this->currentLanguage . '_Name = "", l' . $this->primaryLanguage . '_Name, l' . $this->currentLanguage . '_Name) AS Name, IsoCode
FROM ' . $this->Application->getUnitConfig('country-state')->getTableName() . '
WHERE (Type = ' . DESTINATION_TYPE_STATE . ') AND (StateCountryId = ' . $country_id . ')
ORDER BY Name ASC';
$states = $this->Conn->GetCol($sql, 'IsoCode');
$this->Application->setCache($cache_key, $states);
}
return $states;
}
/**
* Returns valid state ISO code for state name and country code passed
*
* @param string $state_name
* @param string $country_iso
* @return string
*/
function getStateIso($state_name, $country_iso)
{
if ( !$this->CountryHasStates($country_iso) ) {
return $state_name;
}
$table_name = $this->Application->getUnitConfig('country-state')->getTableName();
$country_id = $this->getCountryStateId($country_iso, DESTINATION_TYPE_COUNTRY);
$sql = 'SELECT IsoCode
FROM ' . $table_name . '
WHERE (Type = ' . DESTINATION_TYPE_STATE . ') AND (StateCountryId = %1$s) AND
(
(IsoCode = %2$s) OR (UPPER(l%3$s_Name) = %2$s) OR (UPPER(l%4$s_Name) = %2$s)
)';
$state_name = trim(mb_strtoupper($state_name));
$sql = sprintf($sql, $country_id, $this->Conn->qstr($state_name), $this->currentLanguage, $this->primaryLanguage);
return $this->Conn->GetOne($sql);
}
/**
* Checks, that entered state matches entered country
*
* @param kEvent $event
* @param string $state_field
* @param string $country_field
* @param bool $auto_required
* @return void
*/
function CheckStateField($event, $state_field, $country_field, $auto_required = true)
{
$object = $event->getObject();
/* @var $object kDBItem */
$country_iso = $object->GetDBField($country_field);
if ( $auto_required ) {
$object->setRequired($state_field, $this->CountryHasStates($country_iso));
}
$state = $object->GetDBField($state_field);
if ( $country_iso && $state ) {
$state_iso = $this->getStateIso($state, $country_iso);
if ( $state_iso !== false ) {
// replace state name with it's ISO code
$object->SetDBField($state_field, $state_iso);
}
else {
// state not found by name -> report error
$object->SetError($state_field, 'invalid_state', 'la_invalid_state');
}
}
}
/**
* Returns country/state id based on given iso code and it's type
*
* @param string $iso_code
* @param int $type
* @return int
*/
function getCountryStateId($iso_code, $type)
{
$config = $this->Application->getUnitConfig('country-state');
$cache_key = 'country_state_id[%CountryStateSerial%]:ISO=' . $iso_code . ';Type=' . $type;
$id = $this->Application->getCache($cache_key);
if ( $id === false ) {
$sql = 'SELECT ' . $config->getIDField() . '
FROM ' . $config->getTableName() . '
WHERE (Type = ' . $type . ') AND (IsoCode = ' . $this->Conn->qstr($iso_code) . ')';
$id = (int)$this->Conn->GetOne($sql);
$this->Application->setCache($cache_key, $id);
}
return $id;
}
/**
* Returns 3 symbols ISO code from 2 symbols ISO code or otherwise, when $from_short parameter is used
*
* @param string $iso_code
* @param bool $from_short
* @return string
*/
function getCountryIso($iso_code, $from_short = false)
{
if ($from_short) {
$sql = 'SELECT IsoCode
FROM ' . TABLE_PREFIX . 'CountryStates
WHERE ShortIsoCode = ' . $this->Conn->qstr($iso_code) . ' AND `Type` = ' . DESTINATION_TYPE_COUNTRY;
}
else {
$sql = 'SELECT ShortIsoCode
FROM ' . TABLE_PREFIX . 'CountryStates
WHERE IsoCode = ' . $this->Conn->qstr($iso_code) . ' AND `Type` = ' . DESTINATION_TYPE_COUNTRY;
}
return $this->Conn->GetOne($sql);
}
}

Event Timeline