<?php
/**
* SocialEngine
*
* @category Application_Extensions
* @package Phpfoximporter
* @copyright Copyright 2006-2020 Webligo Developments
* @license http://www.socialengine.com/license/
* @version PhpfoxAbstract.php 2015-07-30 00:00:00Z john $
* @author John
*/
abstract class Install_Import_PhpfoxAbstract
{
protected $_fromPath;
protected $_toDb;
protected $_fromPrefix;
protected $_toPath;
protected $_toTable;
protected $_toTableTruncate = true;
protected $_toTableExists;
protected $_messages = array();
protected $_priority = 100;
protected $_requires = array();
protected $_verbosity = 1;
protected $_hasError = false;
protected $_hasWarning = false;
protected $_params;
protected $_log;
protected $_cache;
protected $_batchCount;
protected $_isComplete = false;
protected $_staticSalt;
protected $_currencyType;
protected $_fromOrderBy = null;
protected $_warningMessage = array();
protected $_settingEnable = null;
protected $_customFields = null;
protected $_fromGroupBy = null;
protected $_fileSize = null;
protected $_messageCount = 0;
// Special
final public function __construct(array $options)
{
@set_time_limit(0);
@ini_set('memory_limit', -1);
$this->setOptions($options);
$this->init();
}
final public function setOptions(array $options)
{
foreach( $options as $key => $value ) {
$method = 'set' . ucfirst($key);
if( method_exists($this, $method) ) {
$this->$method($value);
} else {
$this->_params[$key] = $value;
}
}
return $this;
}
public function __sleep()
{
return array(
'_fromPath', '_fromPrefix', '_toPath', '_toTable', '_toTableTruncate',
'_toTableExists', '_messages', '_priority', '_requires', '_verbosity',
'_hasError', '_hasWarning', '_params', '_batchCount', '_isComplete',
'_staticSalt', '_currencyType', '_fromOrderBy', '_warningMessage',
'_settingEnable', '_customFields', '_fromGroupBy', '_fileSize', '_messageCount'
);
}
// Options
public function setToDb(Zend_Db_Adapter_Abstract $toDb)
{
$this->_toDb = $toDb;
return $this;
}
/**
* @return Zend_Db_Adapter_Abstract
*/
public function getToDb()
{
if( null === $this->_toDb ) {
throw new Engine_Exception('No to database');
}
return $this->_toDb;
}
public function setToPath($toPath)
{
$this->_toPath = $toPath;
return $this;
}
public function getToPath()
{
if( null === $this->_toPath ) {
throw new Engine_Exception('No to path');
}
return $this->_toPath;
}
public function getFromPrefix()
{
if( null === $this->_fromPrefix ) {
throw new Engine_Exception('No prefix');
}
return $this->_fromPrefix;
}
public function setFromPrefix($fromPrefix)
{
$this->_fromPrefix = $fromPrefix;
return $this;
}
public function setToTable($toTable)
{
$this->_toTable = $toTable;
return $this;
}
public function getToTable()
{
if( null === $this->_toTable ) {
throw new Engine_Exception('No to table');
}
return $this->_toTable;
}
public function getToTableExists()
{
if( null === $this->_toTable ) {
return false;
}
if( null === $this->_toTableExists ) {
$this->_toTableExists = $this->_tableExists($this->getToDb(), $this->getToTable());
}
return $this->_toTableExists;
}
public function setFromPath($fromPath)
{
$this->_fromPath = $fromPath;
return $this;
}
public function getFromPath()
{
if( null === $this->_fromPath ) {
throw new Engine_Exception('No from path');
}
return $this->_fromPath;
}
public function setPriority($priority = 100)
{
$this->_priority = (int) $priority;
return $this;
}
public function getPriority()
{
return $this->_priority;
}
public function setRequires(array $requires)
{
$this->_requires = $requires;
return $this->_requires;
}
public function getRequires()
{
return $this->_requires;
}
public function setVerbosity($verbosity)
{
$this->_verbosity = (integer) $verbosity;
return $this;
}
public function getVerbosity()
{
return $this->_verbosity;
}
public function setParams(array $params = array())
{
$this->_params = $params;
return $this;
}
public function getParams()
{
return $this->_params;
}
public function getParam($key, $default = null)
{
if( array_key_exists($key, (array) $this->_params) ) {
return $this->_params[$key];
} else {
return $default;
}
}
// Messages
public function setLog(Zend_Log $log)
{
$this->_log = $log;
}
public function getLog()
{
if( null === $this->_log ) {
$log = new Zend_Log();
$log->addWriter(new Zend_Log_Writer_Stream(APPLICATION_PATH . '/temporary/log/import-phpfox.log', 'a'));
$this->_log = $log;
}
return $this->_log;
}
public function getMessages()
{
return $this->_messages;
}
public function hasError()
{
return $this->_hasError;
}
public function hasWarning()
{
return $this->_hasWarning;
}
protected function _message($message, $verbosity = 1)
{
$this->_log($message, Zend_Log::INFO);
if( $verbosity <= $this->getVerbosity() ) {
if( $message instanceof Exception ) {
$message = $message->getMessage();
}
$this->_messages[] = get_class($this) . ': ' . $message;
}
return $this;
}
protected function _warning($message, $verbosity = 0)
{
$this->_log($message, Zend_Log::WARN);
if( $verbosity <= $this->getVerbosity() ) {
if( $message instanceof Exception ) {
$message = $message->getMessage();
}
$this->_hasWarning = true;
$this->_messages[] = get_class($this) . ': Warning: ' . $message;
// Send an email
if( false != ($email = $this->getParam('email')) && in_array('warning', (array) $this->getParam('emailOptions')) ) {
try {
$now = gmdate('c', time());
$mail = new Zend_Mail();
$mail
->setFrom('no-reply@' . $_SERVER['HTTP_HOST'])
->addTo($email)
->setSubject('SocialEngine PHPFox Migration Progress for ' . $_SERVER['HTTP_HOST'])
->setBodyText("Hello,
This is a SocialEngine PHPFox migration status report.
Server: {$_SERVER['HTTP_HOST']}
Time: {$now}
Message: A warning has occurred. {$message}
Regards,
Your Server")
;
} catch( Exception $e ) {
// Silence
}
}
}
return $this;
}
protected function _error($message, $verbosity = 0)
{
$this->_log($message, Zend_Log::ERR);
if( $verbosity <= $this->getVerbosity() ) {
if( $message instanceof Exception ) {
$message = $message->getMessage();
}
$this->_hasError = true;
$this->_messages[] = get_class($this) . ': Error: ' . $message;
// Send an email
if( false != ($email = $this->getParam('email')) && in_array('error', (array) $this->getParam('emailOptions')) ) {
try {
$now = gmdate('c', time());
$mail = new Zend_Mail();
$mail
->setFrom('no-reply@' . $_SERVER['HTTP_HOST'])
->addTo($email)
->setSubject('SocialEngine PHPFox Migration Progress for ' . $_SERVER['HTTP_HOST'])
->setBodyText("Hello,
This is a SocialEngine PHPFox migration status report.
Server: {$_SERVER['HTTP_HOST']}
Time: {$now}
Message: An error has occurred. {$message}
Regards,
Your Server")
;
} catch( Exception $e ) {
// Silence
}
}
}
return $this;
}
protected function _log($message, $level = Zend_Log::INFO)
{
if( $message instanceof Exception ) {
$message = $message->__toString();
}
$this->getLog()->log(get_class($this) . ' - ' . $message, $level);
}
protected function _logFile($message, $level = Zend_Log::INFO)
{
if( $message instanceof Exception ) {
$message = $message->getMessage();
}
$this->getLog()->log(get_class($this) . ' - ' . $message, $level);
}
// Cache
public function setCache(Zend_Cache_Core $cache)
{
$this->_cache = $cache;
return $this;
}
/**
* @return Zend_Cache_Core
*/
public function getCache()
{
return $this->_cache;
}
public function setBatchCount($batchCount)
{
$this->_batchCount = (int) $batchCount;
return $this;
}
public function getBatchCount()
{
return $this->_batchCount;
}
public function isComplete()
{
return (bool) $this->_isComplete;
}
// Custom
public function init()
{
$this->_initPre();
$this->_init();
$this->_initPost();
}
abstract public function run();
protected function _initPre()
{
}
protected function _init()
{
}
protected function _initPost()
{
}
protected function _runPre()
{
}
protected function _runPost()
{
}
protected function _translateRow(array $data, $key = null)
{
return false;
}
// Utility
protected function _translateTime($time)
{
if( is_int($time) || is_numeric($time) ) {
} elseif( is_string($time) ) {
$time = strtotime($time);
} else {
$time = 0; // _translateTime must alwasy return a valid date
}
return gmdate('Y-m-d H:i:s', $time);
}
protected function _translateFile($file, array $params, $checkForThumb = true)
{
if( !file_exists($file) ) {
return false;
}
$row = array();
if( !empty($params['parent_file_id']) && !empty($params['type']) ) {
$row['parent_file_id'] = @$params['parent_file_id'];
$row['type'] = @$params['type'];
}
$row['parent_type'] = $params['parent_type'];
$row['parent_id'] = $params['parent_id'];
$row['user_id'] = @$params['user_id'];
$row['creation_date'] = $row['modified_date'] = $this->_translateTime(filemtime($file));
$row['service_id'] = 1;
$row['name'] = basename($file);
$row['extension'] = ltrim(strrchr($file, '.'), '.');
$row['mime_major'] = 'unknown';
$row['mime_minor'] = 'unknown';
$row['size'] = filesize($file);
$row['hash'] = md5_file($file);
$row['storage_path'] = $file; // temporary
// Insert row
$this->getToDb()->insert('engine4_storage_files', $row);
$file_id = $this->getToDb()->lastInsertId();
// Make storage path
extract($row);
$subdir1 = ( (int) $parent_id + 999999 - ( ( (int) $parent_id - 1 ) % 1000000) );
$subdir2 = ( (int) $parent_id + 999 - ( ( (int) $parent_id - 1 ) % 1000 ) );
$row['storage_path'] = // extended by default
'public' . '/'
. strtolower($parent_type) . '/'
. $subdir1 . '/'
. $subdir2 . '/'
. $parent_id . '/'
. $file_id . '.'
. strtolower($extension);
$fullTargetPath = $this->getToPath() . DIRECTORY_SEPARATOR . $row['storage_path'];
// Make dir
if( !is_dir(dirname($fullTargetPath)) ) {
if( !mkdir(dirname($fullTargetPath), 0777, true) ) {
throw new Engine_Exception('Unable to make directory (' . $fullTargetPath . ') for file ' . $file);
}
}
// Copy file
$cpr = copy($file, $fullTargetPath);
if( !$cpr ) {
throw new Engine_Exception('Unable to store file ' . $file);
}
// Update storage path
$this->getToDb()->update('engine4_storage_files', array(
'storage_path' => $row['storage_path'],
), array(
'file_id = ?' => $file_id,
));
// Shall we try to do the thumbnail?
if( $checkForThumb && stripos($file, 'thumb') === false ) {
$noExtName = rtrim(substr($file, 0, strrpos($file, '.')), '.');
$thumbFile = $noExtName . '_thumb.' . $row['extension'];
if( !file_exists($thumbFile) ) {
$thumbFile = $noExtName . '_thumb.jpg';
if( !file_exists($thumbFile) ) {
$thumbFile = $noExtName . '_thumb.gif';
if( !file_exists($thumbFile) ) {
$thumbFile = null;
}
}
}
if( $thumbFile ) {
$thumbParams = $params;
$thumbParams['parent_file_id'] = $file_id;
$thumbParams['type'] = 'thumb.normal';
try {
$this->_translateFile($thumbFile, $thumbParams);
} catch( Exception $e ) {
}
}
}
return $file_id;
}
function remoteFileExists($url)
{
$curl = curl_init($url);
//don't fetch the actual page, you only want to check the connection is ok
curl_setopt($curl, CURLOPT_NOBODY, true);
//do request
$result = curl_exec($curl);
$ret = false;
//if request did not fail
if( $result !== false ) {
//if request was ok, check response code
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if( $statusCode == 200 ) {
$ret = true;
}
}
curl_close($curl);
return $ret;
}
protected function _translatePhoto($file, array $params)
{
if( isset($params['remoteServer']) ) {
if( !$this->remoteFileExists($file) ) {
return false;
}
} else {
if( !file_exists($file) ) {
return false;
}
}
$file_id = false;
$name = basename($file);
$temporaryDirectory = $this->_sys_get_temp_dir();
$mainFile = $temporaryDirectory . '/m_' . $name;
$profileFile = $temporaryDirectory . '/p_' . $name;
$normalFile = $temporaryDirectory . '/n_' . $name;
$squareFile = $temporaryDirectory . '/s_' . $name;
try {
// Resize image (main)
$image = Engine_Image::factory();
$image->open($file)
->resize(1600, 1600)
->write($mainFile)
->destroy();
// Resize image (profile)
$image = Engine_Image::factory();
$image->open($file)
->resize(200, 400)
->write($profileFile)
->destroy();
// Resize image (normal)
$image = Engine_Image::factory();
$image->open($file)
->resize(375, 375)
->write($normalFile)
->destroy();
// Resize image (icon)
$image = Engine_Image::factory();
$image->open($file);
$size = min($image->height, $image->width);
$x = ($image->width - $size) / 2;
$y = ($image->height - $size) / 2;
$image->resample($x, $y, $size, $size, 48, 48)
->write($squareFile)
->destroy();
// Store
$file_id = $this->_translateFile($mainFile, $params, false);
if( !$file_id )
return false;
$this->_translateFile($profileFile, array_merge($params, array(
'parent_file_id' => $file_id,
'type' => 'thumb.profile',
)), false);
$this->_translateFile($normalFile, array_merge($params, array(
'parent_file_id' => $file_id,
'type' => 'thumb.normal',
)), false);
$this->_translateFile($squareFile, array_merge($params, array(
'parent_file_id' => $file_id,
'type' => 'thumb.icon',
)), false);
// Remove temp files
@unlink($mainFile);
@unlink($profileFile);
@unlink($normalFile);
@unlink($$squareFile);
} catch( Exception $ex ) {
throw $ex;
}
return $file_id;
}
protected function _sys_get_temp_dir()
{
return APPLICATION_PATH . '/temporary';
if( !function_exists('sys_get_temp_dir') ) {
function sys_get_temp_dir()
{
if( false != ($temp = getenv('TMP')) )
return $temp;
if( false != ($temp = getenv('TEMP')) )
return $temp;
if( false != ($temp = getenv('TMPDIR')) )
return $temp;
$temp = tempnam(__FILE__, '');
if( file_exists($temp) ) {
unlink($temp);
return dirname($temp);
}
return null;
}
}
return sys_get_temp_dir();
}
protected function _unserialize($string)
{
$data = unserialize($string);
if( !$data || !is_array($data) ) {
$data = $this->_mb_unserialize($string);
if( !$data || !is_array($data) ) {
throw new Engine_Exception('Unable to unserialize string');
}
}
return $data;
}
protected function _mb_unserialize($serial_str)
{
$out = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str);
return unserialize($out);
}
protected function _truncateTable(Zend_Db_Adapter_Abstract $db, $table)
{
try {
$this->_message('Truncating table: ' . $table, 2);
$this->getToDb()->query('TRUNCATE TABLE ' . $db->quoteIdentifier($table));
} catch( Exception $e ) {
return false;
}
return true;
}
protected function _truncateToTable()
{
if( $this->_toTable ) {
try {
return $this->_truncateTable($this->getToDb(), $this->getToTable());
} catch( Exception $e ) {
return false;
}
}
return false;
}
protected function _insertOrUpdate(Zend_Db_Adapter_Abstract $db, $table, $insert, $update)
{
list($sql, $bind) = $this->_generateInsert($db, $table, $insert);
$sql .= ' ON DUPLICATE KEY UPDATE ';
$i = 0;
foreach( $update as $col => $val ) {
if( $i > 0 ) {
$sql .= ', ';
}
$sql .= $db->quoteIdentifier($col, true) . '=';
if( $val instanceof Zend_Db_Expr ) {
$sql .= $val->__toString();
} else {
$sql .= '?';
$bind[] = $val;
}
$i++;
}
// execute the statement and return the number of affected rows
$stmt = $db->query($sql, array_values($bind));
$result = $stmt->rowCount();
return $result;
}
protected function _generateInsert(Zend_Db_Adapter_Abstract $db, $table, $bind)
{
// extract and quote col names from the array keys
$cols = array();
$vals = array();
foreach( $bind as $col => $val ) {
$cols[] = $db->quoteIdentifier($col, true);
if( $val instanceof Zend_Db_Expr ) {
$vals[] = $val->__toString();
unset($bind[$col]);
} else {
$vals[] = '?';
}
}
// build the statement
$sql = "INSERT INTO "
. $db->quoteIdentifier($table, true)
. ' (' . implode(', ', $cols) . ') '
. 'VALUES (' . implode(', ', $vals) . ')';
return array($sql, array_values($bind));
}
protected function _tableExists(Zend_Db_Adapter_Abstract $db, $table)
{
if( is_array($table) ) {
$exists = true;
foreach( $table as $singleTable ) {
$exists &= $this->_tableExists($db, $singleTable);
}
return $exists;
}
$sql = 'SHOW TABLES LIKE ' . $db->quote($table);
$ret = $db->query($sql)->fetchColumn();
if( !$ret ) {
return false;
} else {
return true;
}
}
}