Merge branch 'development' of https://github.com/MPOS/php-mpos into development
This commit is contained in:
commit
722642f39c
@ -54,10 +54,18 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
$log->logInfo(sprintf($strLogMask, $aBlock['id'], $aBlock['height'], $aBlock['blockhash'], $aBlock['confirmations'], $aBlockInfo['confirmations'], $status));
|
||||
continue;
|
||||
}
|
||||
if ($aBlock['confirmations'] == $aBlockInfo['confirmations']) {
|
||||
if (isset($aBlockInfo['confirmations'])) {
|
||||
$iRPCConfirmations = $aBlockInfo['confirmations'];
|
||||
} else if (isset($aTxDetails['confirmations'])) {
|
||||
$iRPCConfirmations = $aTxDetails['confirmations'];
|
||||
} else {
|
||||
$log->logFatal(' RPC does not return any usable block confirmation information');
|
||||
$monitoring->endCronjob($cron_name, 'E0082', 1, true);
|
||||
}
|
||||
if ($iRPCConfirmations == $aBlock['confirmations']) {
|
||||
continue;
|
||||
} else {
|
||||
if (!$block->setConfirmations($aBlock['id'], $aBlockInfo['confirmations'])) {
|
||||
if (!$block->setConfirmations($aBlock['id'], $iRPCConfirmations)) {
|
||||
$log->logError(' Failed to update block confirmations: ' . $block->getCronMessage());
|
||||
$status = 'ERROR';
|
||||
} else {
|
||||
@ -67,7 +75,7 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
$log->logInfo(sprintf($strLogMask, 'ID', 'Height', 'Blockhash', 'Old', 'New', 'Status'));
|
||||
$header = true;
|
||||
}
|
||||
$log->logInfo(sprintf($strLogMask, $aBlock['id'], $aBlock['height'], $aBlock['blockhash'], $aBlock['confirmations'], $aBlockInfo['confirmations'], $status));
|
||||
$log->logInfo(sprintf($strLogMask, $aBlock['id'], $aBlock['height'], $aBlock['blockhash'], $aBlock['confirmations'], $iRPCConfirmations, $status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"./logs/*.txt" {
|
||||
"./logs/*/*.txt" {
|
||||
copytruncate
|
||||
rotate 7
|
||||
compress
|
||||
|
||||
@ -26,7 +26,7 @@ chdir(dirname(__FILE__));
|
||||
require_once('shared.inc.php');
|
||||
|
||||
// Fetch our last block found from the DB as a starting point
|
||||
$aLastBlock = @$block->getLast();
|
||||
$aLastBlock = @$block->getLastValid();
|
||||
$strLastBlockHash = $aLastBlock['blockhash'];
|
||||
if (!$strLastBlockHash) $strLastBlockHash = '';
|
||||
|
||||
@ -58,6 +58,15 @@ if (empty($aTransactions['transactions'])) {
|
||||
$aBlockRPCInfo = $bitcoin->getblock($aData['blockhash']);
|
||||
$config['reward_type'] == 'block' ? $aData['amount'] = $aData['amount'] : $aData['amount'] = $config['reward'];
|
||||
$aData['height'] = $aBlockRPCInfo['height'];
|
||||
$aTxDetails = $bitcoin->gettransaction($aBlockRPCInfo['tx'][0]);
|
||||
if (!isset($aBlockRPCInfo['confirmations'])) {
|
||||
$aData['confirmations'] = $aBlockRPCInfo['confirmations'];
|
||||
} else if (isset($aTxDetails['confirmations'])) {
|
||||
$aData['confirmations'] = $aTxDetails['confirmations'];
|
||||
} else {
|
||||
$log->logFatal(' RPC does not return any usable block confirmation information');
|
||||
$monitoring->endCronjob($cron_name, 'E0082', 1, true);
|
||||
}
|
||||
$aData['difficulty'] = $aBlockRPCInfo['difficulty'];
|
||||
$log->logInfo(sprintf($strLogMask, substr($aData['blockhash'], 0, 17)."...", $aData['height'], $aData['amount'], $aData['confirmations'], $aData['difficulty'], strftime("%Y-%m-%d %H:%M:%S", $aData['time'])));
|
||||
if ( ! empty($aBlockRPCInfo['flags']) && preg_match('/proof-of-stake/', $aBlockRPCInfo['flags']) ) {
|
||||
|
||||
@ -29,47 +29,49 @@ if ($setting->getValue('disable_notifications') == 1) {
|
||||
$monitoring->endCronjob($cron_name, 'E0009', 0, true, false);
|
||||
}
|
||||
|
||||
$log->logDebug(" IDLE Worker Notifications ...");
|
||||
// Find all IDLE workers
|
||||
$aWorkers = $worker->getAllIdleWorkers();
|
||||
if (empty($aWorkers)) {
|
||||
$log->logDebug(" no idle workers found");
|
||||
} else {
|
||||
$log->logInfo(" found " . count($aWorkers) . " IDLE workers");
|
||||
foreach ($aWorkers as $aWorker) {
|
||||
$aData = $aWorker;
|
||||
$aData['username'] = $user->getUserName($aWorker['account_id']);
|
||||
$aData['subject'] = 'IDLE Worker : ' . $aWorker['username'];
|
||||
$aData['worker'] = $aWorker['username'];
|
||||
$aData['email'] = $user->getUserEmail($aData['username']);
|
||||
$log->logDebug(" " . $aWorker['username'] . "...");
|
||||
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData))
|
||||
$log->logDebug(" Failed sending notifications: " . $notification->getCronError());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$log->logDebug(" Reset IDLE Worker Notifications ...");
|
||||
// We notified, lets check which recovered
|
||||
$aNotifications = $notification->getAllActive('idle_worker');
|
||||
if (!empty($aNotifications)) {
|
||||
$log->logInfo(" found " . count($aNotifications) . " active notification(s)");
|
||||
foreach ($aNotifications as $aNotification) {
|
||||
$aData = json_decode($aNotification['data'], true);
|
||||
$aWorker = $worker->getWorker($aData['id']);
|
||||
$log->logDebug(" " . $aWorker['username'] . " ...");
|
||||
if ($aWorker['hashrate'] > 0) {
|
||||
if ($notification->setInactive($aNotification['id'])) {
|
||||
$log->logDebug(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive");
|
||||
} else {
|
||||
$log->logError(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username']);
|
||||
}
|
||||
} else {
|
||||
$log->logDebug(" still inactive");
|
||||
if ($setting->getValue('notifications_disable_idle_worker') != 1) {
|
||||
$log->logDebug(" IDLE Worker Notifications ...");
|
||||
// Find all IDLE workers
|
||||
$aWorkers = $worker->getAllIdleWorkers();
|
||||
if (empty($aWorkers)) {
|
||||
$log->logDebug(" no idle workers found");
|
||||
} else {
|
||||
$log->logInfo(" found " . count($aWorkers) . " IDLE workers");
|
||||
foreach ($aWorkers as $aWorker) {
|
||||
$aData = $aWorker;
|
||||
$aData['username'] = $user->getUserName($aWorker['account_id']);
|
||||
$aData['subject'] = 'IDLE Worker : ' . $aWorker['username'];
|
||||
$aData['worker'] = $aWorker['username'];
|
||||
$aData['email'] = $user->getUserEmail($aData['username']);
|
||||
$log->logDebug(" " . $aWorker['username'] . "...");
|
||||
if (!$notification->sendNotification($aWorker['account_id'], 'idle_worker', $aData))
|
||||
$log->logDebug(" Failed sending notifications: " . $notification->getCronError());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$log->logDebug(" no active IDLE worker notifications");
|
||||
|
||||
|
||||
$log->logDebug(" Reset IDLE Worker Notifications ...");
|
||||
// We notified, lets check which recovered
|
||||
$aNotifications = $notification->getAllActive('idle_worker');
|
||||
if (!empty($aNotifications)) {
|
||||
$log->logInfo(" found " . count($aNotifications) . " active notification(s)");
|
||||
foreach ($aNotifications as $aNotification) {
|
||||
$aData = json_decode($aNotification['data'], true);
|
||||
$aWorker = $worker->getWorker($aData['id']);
|
||||
$log->logDebug(" " . $aWorker['username'] . " ...");
|
||||
if ($aWorker['hashrate'] > 0) {
|
||||
if ($notification->setInactive($aNotification['id'])) {
|
||||
$log->logDebug(" updated #" . $aNotification['id'] . " for " . $aWorker['username'] . " as inactive");
|
||||
} else {
|
||||
$log->logError(" failed to update #" . $aNotification['id'] . " for " . $aWorker['username']);
|
||||
}
|
||||
} else {
|
||||
$log->logDebug(" still inactive");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$log->logDebug(" no active IDLE worker notifications");
|
||||
}
|
||||
}
|
||||
|
||||
require_once('cron_end.inc.php');
|
||||
|
||||
@ -48,10 +48,10 @@ if (!$dWalletBalance = $bitcoin->getrealbalance())
|
||||
empty($config['network_confirmations']) ? $confirmations = 120 : $confirmations = $config['network_confirmations'];
|
||||
$aBlocksUnconfirmed = $block->getAllUnconfirmed($confirmations);
|
||||
$dBlocksUnconfirmedBalance = 0;
|
||||
if (!empty($aBlocksUnconfirmed))foreach ($aBlocksUnconfirmed as $aData) $dBlocksUnconfirmedBalance += $aData['amount'];
|
||||
|
||||
$dWalletBalance -= $dBlocksUnconfirmedBalance;
|
||||
|
||||
if (!empty($aBlocksUnconfirmed))foreach ($aBlocksUnconfirmed as $aData) $dBlocksUnconfirmedBalance += $aData['amount'];
|
||||
if ($config['getbalancewithunconfirmed']) {
|
||||
$dWalletBalance -= $dBlocksUnconfirmedBalance;
|
||||
}
|
||||
// Fetch Newmint
|
||||
$aGetInfo = $bitcoin->getinfo();
|
||||
if (is_array($aGetInfo) && array_key_exists('newmint', $aGetInfo)) {
|
||||
@ -135,10 +135,10 @@ if (!$dWalletBalance = $bitcoin->getrealbalance())
|
||||
empty($config['network_confirmations']) ? $confirmations = 120 : $confirmations = $config['network_confirmations'];
|
||||
$aBlocksUnconfirmed = $block->getAllUnconfirmed($confirmations);
|
||||
$dBlocksUnconfirmedBalance = 0;
|
||||
if (!empty($aBlocksUnconfirmed))foreach ($aBlocksUnconfirmed as $aData) $dBlocksUnconfirmedBalance += $aData['amount'];
|
||||
|
||||
$dWalletBalance -= $dBlocksUnconfirmedBalance;
|
||||
|
||||
if (!empty($aBlocksUnconfirmed))foreach ($aBlocksUnconfirmed as $aData) $dBlocksUnconfirmedBalance += $aData['amount'];
|
||||
if ($config['getbalancewithunconfirmed']) {
|
||||
$dWalletBalance -= $dBlocksUnconfirmedBalance;
|
||||
}
|
||||
// Fetch Newmint
|
||||
$aGetInfo = $bitcoin->getinfo();
|
||||
if (is_array($aGetInfo) && array_key_exists('newmint', $aGetInfo)) {
|
||||
|
||||
@ -181,8 +181,8 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
}
|
||||
|
||||
// Table header for account shares
|
||||
$strLogMask = "| %5.5s | %-15.15s | %15.15s | %15.15s | %12.12s | %20.20s | %20.20s | %20.20s |";
|
||||
$log->logInfo(sprintf($strLogMask, 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee'));
|
||||
$strLogMask = "| %5.5s | %-15.15s | %15.15s | %15.15s | %12.12s | %15.15s | %15.15s | %15.15s | %15.15s |";
|
||||
$log->logInfo(sprintf($strLogMask, 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus'));
|
||||
|
||||
// Loop through all accounts that have found shares for this round
|
||||
foreach ($aTotalAccountShares as $key => $aData) {
|
||||
@ -201,16 +201,28 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
// Defaults
|
||||
$aData['fee' ] = 0;
|
||||
$aData['donation'] = 0;
|
||||
$aData['pool_bonus'] = 0;
|
||||
|
||||
// Calculate pool fees
|
||||
if ($config['fees'] > 0 && $aData['no_fees'] == 0)
|
||||
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);
|
||||
|
||||
// Calculate pool bonus if it applies, will be paid from liquid assets!
|
||||
if ($config['pool_bonus'] > 0) {
|
||||
if ($config['pool_bonus_type'] == 'block') {
|
||||
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $dReward, 8);
|
||||
} else {
|
||||
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $aData['payout'], 8);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate donation amount, fees not included
|
||||
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);
|
||||
|
||||
// Verbose output of this users calculations
|
||||
$log->logInfo(
|
||||
sprintf($strLogMask, $aData['id'], $aData['username'], $aData['pplns_valid'], $aData['pplns_invalid'],
|
||||
number_format($aData['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8)
|
||||
number_format($aData['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8), number_format($aData['pool_bonus'], 8)
|
||||
)
|
||||
);
|
||||
|
||||
@ -225,6 +237,10 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
if ($aData['donation'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation', $aBlock['id']))
|
||||
$log->logFatal('Failed to insert new Donation transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError() . 'on block ' . $aBlock['id']);
|
||||
// Add new bonus credit
|
||||
if ($aData['pool_bonus'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['pool_bonus'], 'Bonus', $aBlock['id']))
|
||||
$log->logFatal('Failed to insert new Bonus transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError());
|
||||
}
|
||||
|
||||
// Add full round share statistics
|
||||
|
||||
@ -63,7 +63,7 @@ if ($config['pps']['reward']['type'] == 'blockavg' && $block->getBlockCount() >
|
||||
}
|
||||
|
||||
// Per-share value to be paid out to users
|
||||
$pps_value = round($pps_reward / (pow(2, $config['target_bits']) * $dDifficulty), 12);
|
||||
$pps_value = round($coin->calcPPSValue($pps_reward, $dDifficulty), 12);
|
||||
|
||||
// Find our last share accounted and last inserted share for PPS calculations
|
||||
if (!$iPreviousShareId = $setting->getValue('pps_last_share_id')) {
|
||||
@ -105,9 +105,8 @@ foreach ($aAccountShares as $aData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// MPOS uses a base difficulty setting to avoid showing weightened shares
|
||||
// Since we need weightened shares here, we go back to the proper value for payouts
|
||||
$aData['payout'] = round($aData['valid'] * pow(2, ($config['difficulty'] - 16)) * $pps_value, 12);
|
||||
// Payout for this user
|
||||
$aData['payout'] = round($aData['valid'] * $pps_value, 12);
|
||||
|
||||
// Defaults
|
||||
$aData['fee' ] = 0;
|
||||
@ -120,7 +119,7 @@ foreach ($aAccountShares as $aData) {
|
||||
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 12);
|
||||
|
||||
$log->logInfo(sprintf(
|
||||
$strLogMask, $aData['id'], $aData['username'], $aData['invalid'], $aData['valid'] * pow(2, ($config['difficulty'] - 16)),
|
||||
$strLogMask, $aData['id'], $aData['username'], $aData['invalid'], $aData['valid'],
|
||||
number_format($pps_value, 12), number_format($aData['payout'], 12), number_format($aData['donation'], 12), number_format($aData['fee'], 12)
|
||||
));
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ if (empty($aAllBlocks)) {
|
||||
|
||||
$count = 0;
|
||||
// Table header for account shares
|
||||
$strLogMask = "| %10.10s | %-5.5s | %15.15s | %15.15s | %12.12s | %20.20s | %20.20s | %20.20s |";
|
||||
$log->logInfo(sprintf($strLogMask, 'Block', 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee'));
|
||||
$strLogMask = "| %10.10s | %-5.5s | %15.15s | %15.15s | %12.12s | %12.12s | %15.15s | %15.15s | %15.15s | %15.15s |";
|
||||
$log->logInfo(sprintf($strLogMask, 'Block', 'ID', 'Username', 'Valid', 'Invalid', 'Percentage', 'Payout', 'Donation', 'Fee', 'Bonus'));
|
||||
foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
// If we have unaccounted blocks without share_ids, they might not have been inserted yet
|
||||
if (!$aBlock['share_id']) {
|
||||
@ -86,18 +86,30 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
// Defaults
|
||||
$aData['fee' ] = 0;
|
||||
$aData['donation'] = 0;
|
||||
$aData['pool_bonus'] = 0;
|
||||
$aData['percentage'] = round(( 100 / $iRoundShares ) * $aData['valid'], 8);
|
||||
$aData['payout'] = round(( $aData['percentage'] / 100 ) * $dReward, 8);
|
||||
|
||||
// Calculate pool fees if they apply
|
||||
if ($config['fees'] > 0 && $aData['no_fees'] == 0)
|
||||
$aData['fee'] = round($config['fees'] / 100 * $aData['payout'], 8);
|
||||
|
||||
// Calculate pool bonus if it applies, will be paid from liquid assets!
|
||||
if ($config['pool_bonus'] > 0) {
|
||||
if ($config['pool_bonus_type'] == 'block') {
|
||||
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $dReward, 8);
|
||||
} else {
|
||||
$aData['pool_bonus'] = round(( $config['pool_bonus'] / 100 ) * $aData['payout'], 8);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate donation amount, fees not included
|
||||
$aData['donation'] = round($user->getDonatePercent($user->getUserId($aData['username'])) / 100 * ( $aData['payout'] - $aData['fee']), 8);
|
||||
|
||||
// Verbose output of this users calculations
|
||||
$log->logInfo(
|
||||
sprintf($strLogMask, $aBlock['height'], $aData['id'], $aData['username'], $aData['valid'], $aData['invalid'],
|
||||
number_format($aData['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8))
|
||||
number_format($aData['percentage'], 8), number_format($aData['payout'], 8), number_format($aData['donation'], 8), number_format($aData['fee'], 8), number_format($aData['pool_bonus'], 8))
|
||||
);
|
||||
|
||||
// Update user share statistics
|
||||
@ -114,6 +126,10 @@ foreach ($aAllBlocks as $iIndex => $aBlock) {
|
||||
if ($aData['donation'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['donation'], 'Donation', $aBlock['id']))
|
||||
$log->logFatal('Failed to insert new Donation transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError());
|
||||
// Add new bonus credit
|
||||
if ($aData['pool_bonus'] > 0)
|
||||
if (!$transaction->addTransaction($aData['id'], $aData['pool_bonus'], 'Bonus', $aBlock['id']))
|
||||
$log->logFatal('Failed to insert new Bonus transaction to database for ' . $aData['username'] . ': ' . $transaction->getCronError());
|
||||
}
|
||||
|
||||
// Add block as accounted for into settings table
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Please be aware: This cron is deprecated and will be removed. Please read: https://github.com/MPOS/php-mpos/wiki/Cronjobs#setup"
|
||||
sleep 2
|
||||
|
||||
#########################
|
||||
# #
|
||||
|
||||
@ -33,18 +33,26 @@ $log->logInfo('Running periodic tasks to update database values for GUI access')
|
||||
$strLogMask = "| %-25.25s | %15.15s | %8.8s | %-6.6s | %-80.80s |";
|
||||
$log->logInfo(sprintf($strLogMask, 'Method', 'Value', 'Runtime', 'Status', 'Message'));
|
||||
|
||||
empty($config['price']['enabled']) ? $tickerupdate = false : $tickerupdate = $config['price']['enabled'];
|
||||
|
||||
// Fetch latest coin price via API call
|
||||
$start = microtime(true);
|
||||
$message = 'Updated latest ' . $config['currency'] . ' price from ' . $config['price']['url'] . ' API';
|
||||
$status = 'OK';
|
||||
if ($price = $tools->getPrice()) {
|
||||
if (!$setting->setValue('price', $price)) {
|
||||
$message = 'Unable to store new price value: ' . $setting->getCronError();
|
||||
if ($tickerupdate) {
|
||||
$message = 'Updated latest ' . $config['currency'] . ' price from ' . $config['price']['url'] . ' API';
|
||||
$status = 'OK';
|
||||
if ($price = $tools->getPrice()) {
|
||||
if (!$setting->setValue('price', $price)) {
|
||||
$message = 'Unable to store new price value: ' . $setting->getCronError();
|
||||
$status = 'ERROR';
|
||||
}
|
||||
} else {
|
||||
$message = 'Failed to fetch price from API: ' . $tools->getCronError();
|
||||
$status = 'ERROR';
|
||||
}
|
||||
} else {
|
||||
$message = 'Failed to fetch price from API: ' . $tools->getCronError();
|
||||
$status = 'ERROR';
|
||||
$message = 'Tickerupdate is disabled';
|
||||
$status = 'OK';
|
||||
$price = 0;
|
||||
}
|
||||
$log->logInfo(sprintf($strLogMask, 'Price Update', $price, number_format(microtime(true) - $start, 3), $status, $message));
|
||||
|
||||
|
||||
@ -6,25 +6,27 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
|
||||
$notice = array();
|
||||
$enotice = array();
|
||||
$error = array();
|
||||
|
||||
|
||||
// setup some basic stuff for checking - getuid/getpwuid not available on mac/windows
|
||||
$apache_user = 'unknown';
|
||||
if (substr_count(strtolower(PHP_OS), 'nix') > 0) {
|
||||
if (substr_count(strtolower(PHP_OS), 'nix') > 0 || substr_count(strtolower(PHP_OS), 'linux') > 0) {
|
||||
$apache_user = (function_exists('posix_getuid')) ? posix_getuid() : 'unknown';
|
||||
$apache_user = (function_exists('posix_getpwuid')) ? posix_getpwuid($apache_user) : $apache_user;
|
||||
}
|
||||
|
||||
|
||||
// setup checks
|
||||
// logging
|
||||
if ($config['logging']['enabled']) {
|
||||
if (!is_writable($config['logging']['path'])) {
|
||||
$error[] = "Logging is enabled but we can't write in the logging path";
|
||||
$error[] = "Logging is enabled but we can't write in the logfile path";
|
||||
}
|
||||
}
|
||||
|
||||
// check if memcache isn't available but enabled in config -> error
|
||||
if (!class_exists('Memcached') && $config['memcache']['enabled']) {
|
||||
$error[] = "You have memcache enabled in your config and it's not available. Install the package on your system.";
|
||||
$error[] = "You have memcached enabled in your config and it's not available as a PHP module. Install the package on your system.";
|
||||
}
|
||||
|
||||
// if it's not enabled, test it if it exists, if it works -> error tell them to enable, -> otherwise notice it's disabled
|
||||
if (!$config['memcache']['enabled']) {
|
||||
if (PHP_OS == 'WINNT') {
|
||||
@ -38,16 +40,18 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
|
||||
$memcache_test_get = @$memcache_test->get('test_mpos_setval');
|
||||
}
|
||||
if (class_exists('Memcached') && $memcache_test_get == $randmctv) {
|
||||
$error[] = "You have memcache disabled in the config and it's available & works! Enable it.";
|
||||
$error[] = "You have memcache disabled in the config but it's available and works! Enable it for best performance.";
|
||||
} else {
|
||||
$notice[] = "Memcache is disabled; Almost every linux distro has packages for it, you should be using it if you can.";
|
||||
}
|
||||
}
|
||||
|
||||
// check if htaccess exists
|
||||
if (!file_exists(BASEPATH.".htaccess")) {
|
||||
$htaccess_link = "<a href='https://github.com/MPOS/php-mpos/blob/next/public/.htaccess'>.htaccess</a>";
|
||||
$notice[] = "You don't seem to have a .htaccess in your public folder, if you're using apache set it up $htaccess_link";
|
||||
$notice[] = "You don't seem to have a .htaccess in your public folder, if you're using Apache set it up: $htaccess_link";
|
||||
}
|
||||
|
||||
// check if we can write templates/cache and templates/compile -> error
|
||||
if (!is_writable(THEME_DIR.'/cache')) {
|
||||
$error[] = "templates/cache folder is not writable for uid {$apache_user['name']}";
|
||||
@ -55,11 +59,13 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
|
||||
if (!is_writable(THEME_DIR.'/compile')) {
|
||||
$error[] = "templates/compile folder is not writable for uid {$apache_user['name']}";
|
||||
}
|
||||
|
||||
// check if we can write the config files, we should NOT be able to -> error
|
||||
if (is_writable(INCLUDE_DIR.'/config/global.inc.php') || is_writable(INCLUDE_DIR.'/config/global.inc.dist.php') ||
|
||||
is_writable(INCLUDE_DIR.'/config/security.inc.php') || is_writable(INCLUDE_DIR.'/config/security.inc.dist.php')) {
|
||||
$error[] = "Your config files <b>SHOULD NOT be writable to this user</b>!";
|
||||
}
|
||||
|
||||
// check if daemon can connect -> error
|
||||
try {
|
||||
if ($bitcoin->can_connect() !== true) {
|
||||
@ -76,7 +82,7 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
|
||||
if (!$bitcoin->validateaddress($config['coldwallet']['address']))
|
||||
$error[] = "Your cold wallet address is <u>SET and INVALID</u>";
|
||||
}
|
||||
|
||||
|
||||
// check if there is more than one account set on wallet
|
||||
$accounts = $bitcoin->listaccounts();
|
||||
if (count($accounts) > 1 && $accounts[''] <= 0) {
|
||||
@ -85,34 +91,34 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
// if database connection fails -> error
|
||||
$db_connect = new mysqli($config['db']['host'], $config['db']['user'], $config['db']['pass'], $config['db']['name'], $config['db']['port']);
|
||||
if (mysqli_connect_errno() || !array_key_exists('client_info', $db_connect)) {
|
||||
$error[] = "Unable to connect to mysql using provided credentials";
|
||||
}
|
||||
// check anti DOS protection, we need memcache for that
|
||||
if ($config['mc_antidos'] && !$config['memcache']['enabled']) {
|
||||
$error[] = "mc_antidos is enabled and memcache is not, <u>memcache is required</u> to use this";
|
||||
}
|
||||
|
||||
// poke stratum using gettingstarted details -> enotice
|
||||
if (substr_count(strtolower(PHP_OS), 'nix') > 0) {
|
||||
// unix *poke*
|
||||
$socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if ($socket !== false) {
|
||||
$address = @gethostbyname($config['gettingstarted']['stratumurl']);
|
||||
$result = @socket_connect($socket, $address, $config['gettingstarted']['stratumport']);
|
||||
if ($result !== 1) {
|
||||
$enotice[] = "We tried to poke your Stratum server using config->gettingstarted details but it didn't respond";
|
||||
}
|
||||
$close = @socket_close($socket);
|
||||
if (function_exists('socket_create')) {
|
||||
$host = @gethostbyname($config['gettingstarted']['stratumurl']);
|
||||
$port = $config['gettingstarted']['stratumport'];
|
||||
|
||||
if (isset($host) and
|
||||
isset($port) and
|
||||
($socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) and
|
||||
(socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 3, 'usec' => 0))) and
|
||||
(@socket_connect($socket, $host, $port)))
|
||||
{
|
||||
socket_close($socket);
|
||||
} else {
|
||||
$enotice[] = 'We tried to poke your Stratum server using your $config[\'gettingstarted\'] settings but it didn\'t respond - ' . socket_strerror(socket_last_error());
|
||||
}
|
||||
} else {
|
||||
// mac/windows *poke*
|
||||
if (! $fp = @fsockopen($config['gettingstarted']['stratumurl'],$config['gettingstarted']['stratumport'],$errCode,$errStr,1)) {
|
||||
$enotice[] = "We tried to poke your Stratum server using config->gettingstarted details but it didn't respond";
|
||||
// Connect via fsockopen as fallback
|
||||
if (! $fp = @fsockopen($config['gettingstarted']['stratumurl'], $config['gettingstarted']['stratumport'], $errCode, $errStr, 1)) {
|
||||
$enotice[] = 'We tried to poke your Stratum server using your $config[\'gettingstarted\'] settings but it didn\'t respond';
|
||||
}
|
||||
@fclose($fp);
|
||||
}
|
||||
|
||||
|
||||
// security checks
|
||||
// salts too short -> notice, salts default -> error
|
||||
if ((strlen($config['SALT']) < 24) || (strlen($config['SALTY']) < 24) || $config['SALT'] == 'PLEASEMAKEMESOMETHINGRANDOM' || $config['SALTY'] == 'THISSHOULDALSOBERRAANNDDOOM') {
|
||||
@ -122,19 +128,19 @@ if (@$_SESSION['USERDATA']['is_admin'] && $user->isAdmin(@$_SESSION['USERDATA'][
|
||||
$notice[] = "SALT or SALTY is too short, they should be more than 24 characters and changing them will require registering again";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// display the errors
|
||||
foreach ($enotice as $en) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $en, 'TYPE' => 'info');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $en, 'TYPE' => 'alert alert-info');
|
||||
}
|
||||
if (!count($notice) && !count($error)) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'The config options we checked seem OK', 'TYPE' => 'success');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => 'The config options we checked seem OK', 'TYPE' => 'alert alert-success');
|
||||
} else {
|
||||
foreach ($notice as $n) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $n, 'TYPE' => 'warning');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $n, 'TYPE' => 'alert alert-warning');
|
||||
}
|
||||
foreach ($error as $e) {
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $e, 'TYPE' => 'errormsg');
|
||||
$_SESSION['POPUP'][] = array('CONTENT' => $e, 'TYPE' => 'alert alert-danger');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,13 +2,6 @@
|
||||
(SECURITY == "*)WT#&YHfd" && SECHASH_CHECK) ? die("public/index.php -> Set a new SECURITY value to continue") : 0;
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
// SHA/Scrypt check
|
||||
if (empty($config['algorithm']) || $config['algorithm'] == 'scrypt') {
|
||||
$config['target_bits'] = 16;
|
||||
} else {
|
||||
$config['target_bits'] = 32;
|
||||
}
|
||||
|
||||
// Default classes
|
||||
require_once(INCLUDE_DIR . '/lib/KLogger.php');
|
||||
require_once(CLASS_DIR . '/logger.class.php');
|
||||
@ -20,24 +13,31 @@ require_once(INCLUDE_DIR . '/database.inc.php');
|
||||
require_once(INCLUDE_DIR . '/config/memcache_keys.inc.php');
|
||||
require_once(INCLUDE_DIR . '/config/error_codes.inc.php');
|
||||
|
||||
// We need to load these two first
|
||||
// We need to load these first
|
||||
require_once(CLASS_DIR . '/base.class.php');
|
||||
require_once(CLASS_DIR . '/coins/coin_base.class.php');
|
||||
require_once(CLASS_DIR . '/setting.class.php');
|
||||
|
||||
// We need this one in here to properly set our theme
|
||||
require_once(INCLUDE_DIR . '/lib/Mobile_Detect.php');
|
||||
// Now decide on which coin class to load and instantiate
|
||||
if (file_exists(CLASS_DIR . '/coins/coin_' . $config['algorithm'] . '.class.php')) {
|
||||
require_once(CLASS_DIR . '/coins/coin_' . $config['algorithm'] . '.class.php');
|
||||
$coin = new Coin();
|
||||
$coin->setConfig($config);
|
||||
} else {
|
||||
die('Unable to load your coins class definition for ' . $config['algorithm']);
|
||||
}
|
||||
|
||||
// Swiftmailer
|
||||
require_once(INCLUDE_DIR . '/lib/swiftmailer/swift_required.php');
|
||||
|
||||
// Detect device
|
||||
if ($detect->isMobile() && $setting->getValue('website_mobile_theme')) {
|
||||
// Set to mobile theme
|
||||
$setting->getValue('website_mobile_theme') ? $theme = $setting->getValue('website_mobile_theme') : $theme = 'mobile';
|
||||
} else if ( PHP_SAPI == 'cli') {
|
||||
if ( PHP_SAPI == 'cli') {
|
||||
// Create a new compile folder just for crons
|
||||
// We call mail templates directly anyway
|
||||
$theme = 'cron';
|
||||
} else {
|
||||
// Use configured theme, fallback to default theme
|
||||
$setting->getValue('website_theme') ? $theme = $setting->getValue('website_theme') : $theme = 'mpos';
|
||||
$setting->getValue('website_theme') ? $theme = $setting->getValue('website_theme') : $theme = 'bootstrap';
|
||||
}
|
||||
define('THEME', $theme);
|
||||
|
||||
|
||||
@ -11,21 +11,21 @@ define('THEME_DIR', BASEPATH . 'templates');
|
||||
$quickstartlink = "<a href='https://github.com/MPOS/php-mpos/wiki/Quick-Start-Guide' title='MPOS Quick Start Guide'>Quick Start Guide</a>";
|
||||
|
||||
// Include our configuration (holding defines for the requires)
|
||||
if (!include_once(BASEPATH . 'include/config/global.inc.dist.php')) die('Unable to load base global config - '.$quickstartlink);
|
||||
if (!@include_once(BASEPATH . 'include/config/global.inc.php')) die('Unable to load your global config - '.$quickstartlink);
|
||||
if (!include_once(BASEPATH . 'include/config/global.inc.dist.php')) die('Unable to load base global config from ['.BASEPATH . 'include/config/global.inc.dist.php' . '] - '.$quickstartlink);
|
||||
if (!@include_once(BASEPATH . 'include/config/global.inc.php')) die('Unable to load your global config from ['.BASEPATH . 'include/config/global.inc.php' . '] - '.$quickstartlink);
|
||||
|
||||
// load our security configs
|
||||
if (!include_once(BASEPATH . 'include/config/security.inc.dist.php')) die('Unable to load base security config - '.$quickstartlink);
|
||||
if (!include_once(BASEPATH . 'include/config/security.inc.dist.php')) die('Unable to load base security config from ['.BASEPATH . 'include/config/security.inc.dist.php' . '] - '.$quickstartlink);
|
||||
if (@file_exists(BASEPATH . 'include/config/security.inc.php')) include_once(BASEPATH . 'include/config/security.inc.php');
|
||||
|
||||
// start our session, we need it for smarty caching
|
||||
$session_start = @session_start();
|
||||
session_set_cookie_params(time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
|
||||
$session_start = @session_start();
|
||||
if (!$session_start) {
|
||||
$log->log("info", "Forcing session id regeneration, session failed to start [hijack attempt?]");
|
||||
session_destroy();
|
||||
session_regenerate_id(true);
|
||||
session_start();
|
||||
$log->log("info", "Forcing session id regeneration, session failed to start [hijack attempt?]");
|
||||
session_destroy();
|
||||
session_regenerate_id(true);
|
||||
session_start();
|
||||
}
|
||||
@setcookie(session_name(), session_id(), time()+$config['cookie']['duration'], $config['cookie']['path'], $config['cookie']['domain'], $config['cookie']['secure'], $config['cookie']['httponly']);
|
||||
|
||||
@ -36,4 +36,4 @@ $master_template = 'master.tpl';
|
||||
// We include all needed files here, even though our templates could load them themself
|
||||
require_once(INCLUDE_DIR . '/autoloader.inc.php');
|
||||
|
||||
?>
|
||||
?>
|
||||
@ -15,6 +15,7 @@ class Api extends Base {
|
||||
return true;
|
||||
} else {
|
||||
if ($error == true) {
|
||||
unset($_SESSION['POPUP']);
|
||||
header('HTTP/1.1 501 Not implemented');
|
||||
die('501 Not implemented');
|
||||
}
|
||||
|
||||
@ -19,6 +19,9 @@ class Base {
|
||||
public function setDebug($debug) {
|
||||
$this->debug = $debug;
|
||||
}
|
||||
public function setCoin($coin) {
|
||||
$this->coin = $coin;
|
||||
}
|
||||
public function setLog($log) {
|
||||
$this->log = $log;
|
||||
}
|
||||
|
||||
@ -74,6 +74,10 @@ class BitcoinWrapper extends BitcoinClient {
|
||||
if (is_array($dNetworkHashrate)) {
|
||||
if (array_key_exists('networkhashps', $dNetworkHashrate)) {
|
||||
$dNetworkHashrate = $dNetworkHashrate['networkhashps'];
|
||||
} else if (array_key_exists('networkmhps', $dNetworkHashrate)) {
|
||||
$dNetworkHashrate = $dNetworkHashrate['networkmhps'] * 1000 * 1000;
|
||||
} else if (array_key_exists('networkghps', $dNetworkHashrate)) {
|
||||
$dNetworkHashrate = $dNetworkHashrate['networkghps'] * 1000 * 1000 * 1000;
|
||||
} else if (array_key_exists('hashespersec', $dNetworkHashrate)) {
|
||||
$dNetworkHashrate = $dNetworkHashrate['hashespersec'];
|
||||
} else if (array_key_exists('netmhashps', $dNetworkHashrate)) {
|
||||
|
||||
@ -15,6 +15,18 @@ class Block extends Base {
|
||||
return $result->fetch_assoc();
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specific method to fetch the latest block found that is VALID
|
||||
* @param none
|
||||
* @return data array Array with database fields as keys
|
||||
**/
|
||||
public function getLastValid() {
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE confirmations > -1 ORDER BY height DESC LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_assoc();
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific block, by block height
|
||||
|
||||
69
public/include/classes/coins/coin_base.class.php
Normal file
69
public/include/classes/coins/coin_base.class.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
|
||||
/**
|
||||
* Our coin base class that we extend our other coins from
|
||||
*
|
||||
* We are implementing all basic coin methods into this class but it
|
||||
* must be extended for customized coins.
|
||||
**/
|
||||
class CoinBase extends Base {
|
||||
// Our coins target bits
|
||||
protected $target_bits = NULL;
|
||||
|
||||
/**
|
||||
* Read our target bits
|
||||
**/
|
||||
public function getTargetBits() {
|
||||
return $this->target_bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the PPS value for this coin
|
||||
* WARNING: Get this wrong and you will over- or underpay your miners!
|
||||
**/
|
||||
public function calcPPSValue($pps_reward, $dDifficulty) {
|
||||
return ($pps_reward / (pow(2, $this->target_bits) * $dDifficulty));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate our hashrate based on shares inserted to DB
|
||||
* We use diff1 share values, not a baseline one
|
||||
**/
|
||||
public function calcHashrate($shares, $interval) {
|
||||
return $shares * pow(2, $this->target_bits) / $interval / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate estimated shares of this coin, this is using baseline
|
||||
* according to our configuration difficulty
|
||||
**/
|
||||
public function calcEstaimtedShares($dDifficulty) {
|
||||
return (int)round(pow(2, (32 - $this->target_bits)) * $dDifficulty, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate our networks expected time per block
|
||||
**/
|
||||
public function calcNetworkExpectedTimePerBlock($dDifficulty, $dNetworkHashrate) {
|
||||
if ($dNetworkHashrate > 0) {
|
||||
return pow(2, 32) * $dDifficulty / $dNetworkHashrate;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Calculate next expected difficulty based on current difficulty
|
||||
**/
|
||||
public function calcExpectedNextDifficulty($dDifficulty, $dNetworkHashrate) {
|
||||
$iExpectedTimePerBlock = $this->calcNetworkExpectedTimePerBlock($dDifficulty, $dNetworkHashrate);
|
||||
if (!empty($iExpectedTimePerBlock) && $iExpectedTimePerBlock > 0) {
|
||||
return round($dDifficulty * $this->config['cointarget'] / $iExpectedTimePerBlock, 8);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
13
public/include/classes/coins/coin_scrypt.class.php
Normal file
13
public/include/classes/coins/coin_scrypt.class.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
/**
|
||||
* We extend our CoinBase class
|
||||
* No need to change anything, base class supports
|
||||
* scrypt and sha256d
|
||||
**/
|
||||
class Coin extends CoinBase {
|
||||
protected $target_bits = 16;
|
||||
}
|
||||
|
||||
?>
|
||||
13
public/include/classes/coins/coin_sha256d.class.php
Normal file
13
public/include/classes/coins/coin_sha256d.class.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
/**
|
||||
* We extend our CoinBase class
|
||||
* No need to change anything, base class supports
|
||||
* scrypt and sha256d
|
||||
**/
|
||||
class Coin extends CoinBase {
|
||||
protected $target_bits = 32;
|
||||
}
|
||||
|
||||
?>
|
||||
@ -34,7 +34,7 @@ class Mail extends Base {
|
||||
$aData['senderEmail'] = $senderEmail;
|
||||
$aData['senderSubject'] = $senderSubject;
|
||||
$aData['senderMessage'] = $senderMessage;
|
||||
$aData['email'] = $this->setting->getValue('website_email');
|
||||
$aData['email'] = $this->setting->getValue('website_email', 'test@example.com');
|
||||
$aData['subject'] = 'Contact Form';
|
||||
if ($this->sendMail('contactform/body', $aData)) {
|
||||
return true;
|
||||
@ -46,26 +46,64 @@ class Mail extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a mail with templating via Smarty
|
||||
* Send a mail with templating via Smarty and Siftmailer
|
||||
* @param template string Template name within the mail folder, no extension
|
||||
* @param aData array Data array with some required fields
|
||||
* SUBJECT : Mail Subject
|
||||
* subject : Mail Subject
|
||||
* email : Destination address
|
||||
**/
|
||||
public function sendMail($template, $aData) {
|
||||
// Make sure we don't load a cached filed
|
||||
public function sendMail($template, $aData, $throttle=false) {
|
||||
// Prepare SMTP transport and mailer
|
||||
$transport_type = $this->config['swiftmailer']['type'];
|
||||
if ($transport_type == 'sendmail') {
|
||||
$transport = Swift_SendmailTransport::newInstance($this->config['swiftmailer'][$transport_type]['path'] . ' ' . $this->config['swiftmailer'][$transport_type]['options']);
|
||||
} else if ($this->config['swiftmailer']['type'] == 'smtp') {
|
||||
$transport = Swift_SmtpTransport::newInstance($this->config['switfmailer']['smtp']['host'], $this->config['switfmailer']['smtp']['port'], $this->config['switfmailer']['smtp']['encryption']);
|
||||
if (!empty($this->config['switfmailer']['smtp']['username']) && !empty($this->config['switfmailer']['smtp']['password'])) {
|
||||
$transport->setUsername($this->config['switfmailer']['smtp']['username']);
|
||||
$transport->setPassword($this->config['switfmailer']['smtp']['password']);
|
||||
}
|
||||
}
|
||||
$mailer = Swift_Mailer::newInstance($transport);
|
||||
|
||||
// Throttle mails to x per minute, used for newsletter for example
|
||||
if ($this->config['swiftmailer']['type'] == 'smtp' && $throttle) {
|
||||
$mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin(
|
||||
$this->config['switfmailer']['smtp']['throttle'], Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE
|
||||
));
|
||||
}
|
||||
|
||||
// Prepare the smarty templates used
|
||||
$this->smarty->clearCache(BASEPATH . 'templates/mail/' . $template . '.tpl');
|
||||
$this->smarty->clearCache(BASEPATH . 'templates/mail/subject.tpl');
|
||||
$this->smarty->assign('WEBSITENAME', $this->setting->getValue('website_name'));
|
||||
$this->smarty->assign('SUBJECT', $aData['subject']);
|
||||
$this->smarty->assign('DATA', $aData);
|
||||
$headers = 'From: ' . $this->setting->getValue('website_name') . '<' . $this->setting->getValue('website_email') . ">\n";
|
||||
$headers .= "MIME-Version: 1.0\n";
|
||||
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
|
||||
if (strlen(@$aData['senderName']) > 0 && @strlen($aData['senderEmail']) > 0 )
|
||||
$headers .= 'Reply-To: ' . $aData['senderName'] . ' <' . $aData['senderEmail'] . ">\n";
|
||||
if (mail($aData['email'], $this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'), $this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'), $headers))
|
||||
return true;
|
||||
|
||||
// Create new message for Swiftmailer
|
||||
$senderEmail = $this->setting->getValue('website_email', 'test@example.com');
|
||||
$senderName = $this->setting->getValue('website_name', 'test@example.com');
|
||||
$message = Swift_Message::newInstance()
|
||||
->setSubject($this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'))
|
||||
->setFrom(array( $senderEmail => $senderName))
|
||||
->setTo($aData['email'])
|
||||
->setSender($senderEmail)
|
||||
->setReturnPath($senderEmail)
|
||||
->setBody($this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'), 'text/html');
|
||||
if (isset($aData['senderName']) &&
|
||||
isset($aData['senderEmail']) &&
|
||||
strlen($aData['senderName']) > 0 &&
|
||||
strlen($aData['senderEmail']) > 0 &&
|
||||
filter_var($aData['senderEmail'], FILTER_VALIDATE_EMAIL))
|
||||
$message->setReplyTo(array($aData['senderEmail'] => $aData['senderName']));
|
||||
|
||||
// Send message out with configured transport
|
||||
try {
|
||||
if ($mailer->send($message)) return true;
|
||||
} catch (Exception $e) {
|
||||
$this->setErrorMessage($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
$this->setErrorMessage($this->sqlError('E0031'));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ class Monitoring extends Base {
|
||||
$aMonitors = explode(',', $api_keys);
|
||||
foreach ($aMonitors as $aData) {
|
||||
$temp = explode('|', $aData);
|
||||
$aMonitor['api_key'] = $temp[0];
|
||||
$aMonitor['monitor_id'] = $temp[1];
|
||||
$aMonitor['api_key'] = trim($temp[0]);
|
||||
$aMonitor['monitor_id'] = trim($temp[1]);
|
||||
$target = '/getMonitors?apiKey=' . $aMonitor['api_key'] . '&monitors=' . $aMonitor['monitor_id'] . '&format=json&noJsonCallback=1&customUptimeRatio=1-7-30&logs=1';
|
||||
$aMonitorStatus = $this->tools->getApi($url, $target);
|
||||
if (!$aMonitorStatus || @$aMonitorStatus['stat'] == 'fail') {
|
||||
@ -70,9 +70,8 @@ class Monitoring extends Base {
|
||||
if ($query && $query->bind_param('s', $name) && $query->execute() && $result = $query->get_result()) {
|
||||
return $result->fetch_assoc();
|
||||
} else {
|
||||
$this->sqlError();
|
||||
return $this->sqlError();
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
19
public/include/classes/notification.class.php
Executable file → Normal file
19
public/include/classes/notification.class.php
Executable file → Normal file
@ -58,10 +58,10 @@ class Notification extends Mail {
|
||||
* @param id int Account ID
|
||||
* @return array Notification data
|
||||
**/
|
||||
public function getNotifications($account_id) {
|
||||
public function getNotifications($account_id,$limit=50) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE account_id = ? ORDER BY time DESC");
|
||||
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result())
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE account_id = ? ORDER BY time DESC LIMIT ?");
|
||||
if ($stmt && $stmt->bind_param('ii', $account_id, $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
return $this->getError();
|
||||
}
|
||||
@ -72,13 +72,26 @@ class Notification extends Mail {
|
||||
* @return array Notification settings
|
||||
**/
|
||||
public function getNotificationSettings($account_id) {
|
||||
// Some defaults, we cover them here so we can avoid adding default settings on user creation
|
||||
$aDefaults = array( 'newsletter' => 1 );
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("SELECT * FROM $this->tableSettings WHERE account_id = ?");
|
||||
if ($stmt && $stmt->bind_param('i', $account_id) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
if ($result->num_rows > 0) {
|
||||
$aFound = array();
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
if (array_key_exists($row['type'], $aDefaults)) $aFound[] = $row['type'];
|
||||
$aData[$row['type']] = $row['active'];
|
||||
}
|
||||
// Check found types against our defaults, set if required
|
||||
foreach ($aDefaults as $type => $value) {
|
||||
if (!in_array($type, $aFound)) {
|
||||
$aData[$type] = $value;
|
||||
}
|
||||
}
|
||||
return $aData;
|
||||
} else {
|
||||
foreach ($aDefaults as $type => $value) $aData[$type] = $value;
|
||||
return $aData;
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ class RoundStats extends Base {
|
||||
SELECT
|
||||
b.id, height, blockhash, amount, confirmations, difficulty, FROM_UNIXTIME(time) as time, shares,
|
||||
IF(a.is_anonymous, 'anonymous', a.username) AS finder,
|
||||
ROUND((difficulty * 65535) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares,
|
||||
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 0) AS estshares,
|
||||
(time - (SELECT time FROM $this->tableBlocks WHERE height < ? ORDER BY height DESC LIMIT 1)) AS round_time
|
||||
FROM " . $this->block->getTableName() . " as b
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a ON b.account_id = a.id
|
||||
@ -288,3 +288,4 @@ $roundstats->setUser($user);
|
||||
$roundstats->setStatistics($statistics);
|
||||
$roundstats->setBlock($block);
|
||||
$roundstats->setTransaction($transaction);
|
||||
$roundstats->setCoin($coin);
|
||||
|
||||
@ -3,6 +3,30 @@ $defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
class Setting extends Base {
|
||||
protected $table = 'settings';
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* Fetch all values available and cache them in this class
|
||||
* That way we don't fetch them from DB for each call
|
||||
*/
|
||||
public function createCache() {
|
||||
if ($aSettings = $this->getAllAssoc()) {
|
||||
foreach ($aSettings as $key => $aData) {
|
||||
$this->cache[$aData['name']] = $aData['value'];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush our local cache, may be required for upgrades
|
||||
* or other places where we need live data
|
||||
**/
|
||||
public function flushCache() {
|
||||
$this->cache = array();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a value from our table
|
||||
@ -10,6 +34,8 @@ class Setting extends Base {
|
||||
* @return value string Value
|
||||
**/
|
||||
public function getValue($name, $default="") {
|
||||
// Try our class cache first
|
||||
if (isset($this->cache[$name])) return $this->cache[$name];
|
||||
$stmt = $this->mysqli->prepare("SELECT value FROM $this->table WHERE name = ? LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('s', $name) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
if ($result->num_rows > 0) {
|
||||
@ -30,6 +56,8 @@ class Setting extends Base {
|
||||
* @return bool
|
||||
**/
|
||||
public function setValue($name, $value) {
|
||||
// Update local cache too
|
||||
$this->cache[$name] = $value;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
INSERT INTO $this->table (name, value)
|
||||
VALUES (?, ?)
|
||||
@ -44,3 +72,5 @@ $setting = new Setting($debug, $mysqli);
|
||||
$setting->setDebug($debug);
|
||||
$setting->setMysql($mysqli);
|
||||
$setting->setErrorCodes($aErrorCodes);
|
||||
// Fill our class cache with data so we don't have to run SQL queries all the time
|
||||
$setting->createCache();
|
||||
|
||||
@ -75,7 +75,7 @@ class Share Extends Base {
|
||||
**/
|
||||
public function getRoundShares($previous_upstream=0, $current_upstream) {
|
||||
$stmt = $this->mysqli->prepare("SELECT
|
||||
ROUND(IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 8) AS total
|
||||
IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS total
|
||||
FROM $this->table AS s
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON a.username = SUBSTRING_INDEX( s.username , '.', 1 )
|
||||
@ -99,8 +99,8 @@ class Share Extends Base {
|
||||
a.id,
|
||||
SUBSTRING_INDEX( s.username , '.', 1 ) as username,
|
||||
a.no_fees AS no_fees,
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 8) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 8) AS invalid
|
||||
IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) AS valid,
|
||||
IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) AS invalid
|
||||
FROM $this->table AS s
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON a.username = SUBSTRING_INDEX( s.username , '.', 1 )
|
||||
@ -112,16 +112,6 @@ class Share Extends Base {
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the highest available share ID
|
||||
**/
|
||||
function getMaxShareId() {
|
||||
$stmt = $this->mysqli->prepare("SELECT MAX(id) AS id FROM $this->table");
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_object()->id;
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the highest available share ID from archive
|
||||
**/
|
||||
@ -146,8 +136,8 @@ class Share Extends Base {
|
||||
a.id,
|
||||
SUBSTRING_INDEX( s.username , '.', 1 ) as account,
|
||||
a.no_fees AS no_fees,
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 8) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 8) AS invalid
|
||||
IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) AS valid,
|
||||
IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) AS invalid
|
||||
FROM $this->tableArchive AS s
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON a.username = SUBSTRING_INDEX( s.username , '.', 1 )
|
||||
@ -360,8 +350,6 @@ class Share Extends Base {
|
||||
* Fetch the lowest needed share ID from shares
|
||||
**/
|
||||
function getMinimumShareId($iCount, $current_upstream) {
|
||||
// We don't use baseline here to be more accurate
|
||||
$iCount = $iCount * pow(2, ($this->config['difficulty'] - 16));
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT MIN(b.id) AS id FROM
|
||||
(
|
||||
@ -381,8 +369,6 @@ class Share Extends Base {
|
||||
* Fetch the lowest needed share ID from archive
|
||||
**/
|
||||
function getMinArchiveShareId($iCount) {
|
||||
// We don't use baseline here to be more accurate
|
||||
$iCount = $iCount * pow(2, ($this->config['difficulty'] - 16));
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT MIN(b.share_id) AS share_id FROM
|
||||
(
|
||||
|
||||
@ -46,46 +46,48 @@ class Statistics extends Base {
|
||||
IFNULL(SUM(IF(confirmations = -1, 1, 0)), 0) AS TotalOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0, difficulty, 0)), 0) AS TotalDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1, shares, 0))), 0) AS TotalShares,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1, POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty / POW(2, (" . $this->config['difficulty'] . " -16)), 0))), 0) AS TotalEstimatedShares,
|
||||
IFNULL(SUM(IF(confirmations > -1, amount, 0)), 0) AS TotalAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), 1, 0)), 0) AS 1HourTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), 1, 0)), 0) AS 1HourValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), 1, 0)), 0) AS 1HourOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), difficulty, 0)), 0) AS 1HourDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), shares, 0))), 0) AS 1HourShares,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty / POW(2, (" . $this->config['difficulty'] . " -16)), 0))), 0) AS 1HourEstimatedShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 3600 SECOND), amount, 0)), 0) AS 1HourAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), 1, 0)), 0) AS 24HourTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), 1, 0)), 0) AS 24HourValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), 1, 0)), 0) AS 24HourOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), difficulty, 0)), 0) AS 24HourDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), shares, 0))), 0) AS 24HourShares,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty / POW(2, (" . $this->config['difficulty'] . " -16)), 0))), 0) AS 24HourEstimatedShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 86400 SECOND), amount, 0)), 0) AS 24HourAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), 1, 0)), 0) AS 7DaysTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), 1, 0)), 0) AS 7DaysValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), 1, 0)), 0) AS 7DaysOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), difficulty, 0)), 0) AS 7DaysDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), shares, 0))), 0) AS 7DaysShares,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty / POW(2, (" . $this->config['difficulty'] . " -16)), 0))), 0) AS 7DaysEstimatedShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 604800 SECOND), amount, 0)), 0) AS 7DaysAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), 1, 0)), 0) AS 4WeeksTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), 1, 0)), 0) AS 4WeeksValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), 1, 0)), 0) AS 4WeeksOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), difficulty, 0)), 0) AS 4WeeksDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), shares, 0))), 0) AS 4WeeksShares,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty / POW(2, (" . $this->config['difficulty'] . " -16)), 0))), 0) AS 4WeeksEstimatedShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 2419200 SECOND), amount, 0)), 0) AS 4WeeksAmount,
|
||||
IFNULL(SUM(IF(FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), 1, 0)), 0) AS 12MonthTotal,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), 1, 0)), 0) AS 12MonthValid,
|
||||
IFNULL(SUM(IF(confirmations = -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), 1, 0)), 0) AS 12MonthOrphan,
|
||||
IFNULL(SUM(IF(confirmations > 0 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), difficulty, 0)), 0) AS 12MonthDifficulty,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), shares, 0))), 0) AS 12MonthShares,
|
||||
IFNULL(ROUND(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty / POW(2, (" . $this->config['difficulty'] . " -16)), 0))), 0) AS 12MonthEstimatedShares,
|
||||
IFNULL(SUM(IF(confirmations > -1 AND FROM_UNIXTIME(time) >= DATE_SUB(now(), INTERVAL 29030400 SECOND), amount, 0)), 0) AS 12MonthAmount
|
||||
FROM " . $this->block->getTableName());
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $this->memcache->setCache(__FUNCTION__, $result->fetch_assoc());
|
||||
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$aData = $result->fetch_assoc();
|
||||
$aData['TotalEstimatedShares'] = $this->coin->calcEstaimtedShares($aData['TotalDifficulty']);
|
||||
$aData['1HourEstimatedShares'] = $this->coin->calcEstaimtedShares($aData['1HourDifficulty']);
|
||||
$aData['24HourEstimatedShares'] = $this->coin->calcEstaimtedShares($aData['24HourDifficulty']);
|
||||
$aData['7DaysEstimatedShares'] = $this->coin->calcEstaimtedShares($aData['7DaysDifficulty']);
|
||||
$aData['4WeeksEstimatedShares'] = $this->coin->calcEstaimtedShares($aData['4WeeksDifficulty']);
|
||||
$aData['12MonthEstimatedShares'] = $this->coin->calcEstaimtedShares($aData['12MonthDifficulty']);
|
||||
return $this->memcache->setCache(__FUNCTION__, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
@ -102,7 +104,7 @@ class Statistics extends Base {
|
||||
b.*,
|
||||
a.username AS finder,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND((difficulty * POW(2, 32 - " . $this->config['target_bits'] . ")) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares
|
||||
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 0) AS estshares
|
||||
FROM " . $this->block->getTableName() . " AS b
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON b.account_id = a.id
|
||||
@ -125,7 +127,7 @@ class Statistics extends Base {
|
||||
b.*,
|
||||
a.username AS finder,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND((difficulty * POW(2, 32 - " . $this->config['target_bits'] . ")) / POW(2, (" . $this->config['difficulty'] . " -16)), 0) AS estshares
|
||||
ROUND(difficulty * POW(2, 32 - " . $this->coin->getTargetBits() . "), 0) AS estshares
|
||||
FROM " . $this->block->getTableName() . " AS b
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON b.account_id = a.id
|
||||
@ -221,19 +223,22 @@ class Statistics extends Base {
|
||||
SELECT
|
||||
(
|
||||
(
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty))), 0) AS shares
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
) + (
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0) AS hashrate
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty))), 0) AS shares
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
)
|
||||
) AS hashrate
|
||||
) AS shares
|
||||
FROM DUAL");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('iiii', $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) return $this->memcache->setStaticCache(__FUNCTION__, $result->fetch_object()->hashrate);
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('ii', $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) {
|
||||
$hashrate = $this->coin->calcHashrate($result->fetch_object()->shares, $interval);
|
||||
return $this->memcache->setStaticCache(__FUNCTION__, $hashrate);
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
@ -288,8 +293,8 @@ class Statistics extends Base {
|
||||
}
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS invalid
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS invalid
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE UNIX_TIMESTAMP(time) > IFNULL((SELECT MAX(time) FROM " . $this->block->getTableName() . "), 0)");
|
||||
if ( $this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result() )
|
||||
@ -311,8 +316,8 @@ class Statistics extends Base {
|
||||
}
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS invalid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty), 0)), 0), 0) AS invalid,
|
||||
u.id AS id,
|
||||
u.donate_percent AS donate_percent,
|
||||
u.is_anonymous AS is_anonymous,
|
||||
@ -339,7 +344,7 @@ class Statistics extends Base {
|
||||
$data['data'][$row['id']]['is_anonymous'] = $row['is_anonymous'];
|
||||
}
|
||||
}
|
||||
$data['share_id'] = $this->share->getMaxShareId();
|
||||
$data['share_id'] = $this->share->getLastInsertedShareId();
|
||||
return $this->memcache->setCache(STATISTICS_ALL_USER_SHARES, $data);
|
||||
}
|
||||
return $this->sqlError();
|
||||
@ -363,8 +368,8 @@ class Statistics extends Base {
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS invalid
|
||||
ROUND(IFNULL(SUM(IF(our_result='Y', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS valid,
|
||||
ROUND(IFNULL(SUM(IF(our_result='N', IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0)), 0), 0) AS invalid
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE username LIKE ?
|
||||
AND UNIX_TIMESTAMP(time) >IFNULL((SELECT MAX(b.time) FROM " . $this->block->getTableName() . " AS b),0)");
|
||||
@ -446,7 +451,7 @@ class Statistics extends Base {
|
||||
|
||||
/**
|
||||
* Fetch all user hashrates based on shares and archived shares
|
||||
* @return data integer Current Hashrate in khash/s
|
||||
* @return data array Set of all user stats
|
||||
**/
|
||||
public function getAllUserMiningStats($interval=180) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
@ -454,7 +459,7 @@ class Statistics extends Base {
|
||||
SELECT
|
||||
a.id AS id,
|
||||
a.username AS account,
|
||||
IFNULL(ROUND(SUM(t1.difficulty) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000, 2), 0) AS hashrate,
|
||||
IFNULL(SUM(t1.difficulty), 0) AS shares,
|
||||
ROUND(COUNT(t1.id) / ?, 2) AS sharerate,
|
||||
IFNULL(AVG(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS avgsharediff
|
||||
FROM (
|
||||
@ -462,26 +467,27 @@ class Statistics extends Base {
|
||||
id,
|
||||
IF(difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty,
|
||||
username
|
||||
FROM shares
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND) AND our_result = 'Y'
|
||||
UNION
|
||||
SELECT
|
||||
share_id,
|
||||
IF(difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty,
|
||||
username
|
||||
FROM shares_archive
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time > DATE_SUB(now(), INTERVAL ? SECOND) AND our_result = 'Y'
|
||||
) AS t1
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON SUBSTRING_INDEX( t1.username, '.', 1 ) = a.username
|
||||
WHERE a.id IS NOT NULL
|
||||
GROUP BY account
|
||||
ORDER BY hashrate DESC
|
||||
ORDER BY shares DESC
|
||||
");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("iiii", $interval, $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) {
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("iii", $interval, $interval, $interval) && $stmt->execute() && $result = $stmt->get_result() ) {
|
||||
$aData = array();
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$aData['data'][$row['id']] = $row;
|
||||
$aData['data'][$row['id']]['hashrate'] = $this->coin->calcHashrate($row['shares'], $interval);
|
||||
}
|
||||
return $this->memcache->setStaticCache(STATISTICS_ALL_USER_HASHRATES, $aData, 600);
|
||||
} else {
|
||||
@ -494,7 +500,7 @@ class Statistics extends Base {
|
||||
if ($this->getGetCache() && $data = $this->memcache->get(__FUNCTION__ . $account_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
ROUND(IFNULL(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS total
|
||||
ROUND(IFNULL(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0), 0) AS total
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE username LIKE ?
|
||||
AND id > ?
|
||||
@ -527,13 +533,13 @@ class Statistics extends Base {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(COUNT(*) / ?, 0) AS sharerate,
|
||||
IFNULL(ROUND(SUM(difficulty) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000, 2), 0) AS hashrate,
|
||||
IFNULL(SUM(difficulty), 0) AS shares,
|
||||
IFNULL(AVG(difficulty), 0) AS avgsharediff
|
||||
FROM (
|
||||
SELECT
|
||||
id, our_result, IF(difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty
|
||||
FROM
|
||||
shares
|
||||
" . $this->share->getTableName() . "
|
||||
WHERE username LIKE ?
|
||||
AND time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
@ -541,33 +547,17 @@ class Statistics extends Base {
|
||||
SELECT
|
||||
share_id, our_result, IF(difficulty = 0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty) AS difficulty
|
||||
FROM
|
||||
shares_archive
|
||||
" . $this->share->getArchiveTableName() . "
|
||||
WHERE username LIKE ?
|
||||
AND time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
AND our_result = 'Y'
|
||||
) AS temp");
|
||||
$username = $username . ".%";
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("iisisi", $interval, $interval, $username, $interval, $username, $interval) && $stmt->execute() && $result = $stmt->get_result() )
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_assoc());
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hashrate for a specific worker
|
||||
* @param username string username
|
||||
* @return data int Current hashrate in khash/s
|
||||
**/
|
||||
public function getWorkerHashrate($workername, $worker_id=NULL, $interval=180) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $worker_id)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT IFNULL(ROUND(SUM(IF(difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 600 / 1000), 0) AS hashrate
|
||||
FROM " . $this->share->getTableName() . " AS
|
||||
WHERE username = '?'
|
||||
AND our_result = 'Y'
|
||||
AND time > DATE_SUB(now(), INTERVAL ? SECOND)");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("si", $workername, $interval) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $this->memcache->setCache(__FUNCTION__ . $worker_id, (float)$result->fetch_object()->hashrate);
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("isisi", $interval, $username, $interval, $username, $interval) && $stmt->execute() && $result = $stmt->get_result() ) {
|
||||
$aData = $result->fetch_assoc();
|
||||
$aData['hashrate'] = $this->coin->calcHashrate($aData['shares'], $interval);
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
@ -613,7 +603,7 @@ class Statistics extends Base {
|
||||
a.username AS account,
|
||||
a.donate_percent AS donate_percent,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
ROUND(IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) / POW(2, (" . $this->config['difficulty'] . " - 16)), 0) AS shares
|
||||
ROUND(IFNULL(SUM(IF(s.difficulty=0, POW(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0), 0) AS shares
|
||||
FROM " . $this->share->getTableName() . " AS s
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON SUBSTRING_INDEX( s.username, '.', 1 ) = a.username
|
||||
@ -633,7 +623,7 @@ class Statistics extends Base {
|
||||
a.username AS account,
|
||||
a.donate_percent AS donate_percent,
|
||||
a.is_anonymous AS is_anonymous,
|
||||
IFNULL(ROUND(SUM(t1.difficulty) * POW(2, " . $this->config['target_bits'] . ") / 600 / 1000, 2), 0) AS hashrate
|
||||
IFNULL(SUM(t1.difficulty), 0) AS shares
|
||||
FROM
|
||||
(
|
||||
SELECT id, IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty, username FROM " . $this->share->getTableName() . " WHERE time > DATE_SUB(now(), INTERVAL 10 MINUTE) AND our_result = 'Y'
|
||||
@ -643,9 +633,17 @@ class Statistics extends Base {
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON SUBSTRING_INDEX( t1.username, '.', 1 ) = a.username
|
||||
GROUP BY account
|
||||
ORDER BY hashrate DESC LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $this->memcache->setStaticCache(__FUNCTION__ . $type . $limit, $result->fetch_all(MYSQLI_ASSOC));
|
||||
ORDER BY shares DESC LIMIT ?");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $limit) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$aData = array();
|
||||
$count = 0;
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$aData[$count] = $row;
|
||||
$aData[$count]['hashrate'] = $this->coin->calcHashrate($row['shares'], 600);
|
||||
$count++;
|
||||
}
|
||||
return $this->memcache->setStaticCache(__FUNCTION__ . $type . $limit, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
break;
|
||||
}
|
||||
@ -663,7 +661,7 @@ class Statistics extends Base {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
id,
|
||||
IFNULL(ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
IFNULL(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares,
|
||||
HOUR(time) AS hour
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
@ -674,7 +672,7 @@ class Statistics extends Base {
|
||||
UNION
|
||||
SELECT
|
||||
share_id,
|
||||
IFNULL(ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
IFNULL(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)), 0) AS shares,
|
||||
HOUR(time) AS hour
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
@ -688,7 +686,7 @@ class Statistics extends Base {
|
||||
// Initilize array
|
||||
for ($i = 0; $i < 24; $i++) $aData[($iStartHour + $i) % 24] = 0;
|
||||
// Fill data
|
||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += $row['hashrate'];
|
||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $this->coin->calcHashrate($row['shares'], 3600);
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
@ -705,7 +703,7 @@ class Statistics extends Base {
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
id,
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
IFNULL(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getTableName() . " AS s
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
@ -715,7 +713,7 @@ class Statistics extends Base {
|
||||
UNION
|
||||
SELECT
|
||||
share_id,
|
||||
IFNULL(ROUND(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)) * POW(2, " . $this->config['target_bits'] . ") / 3600 / 1000), 0) AS hashrate,
|
||||
IFNULL(SUM(IF(s.difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), s.difficulty)), 0) AS shares,
|
||||
HOUR(s.time) AS hour
|
||||
FROM " . $this->share->getArchiveTableName() . " AS s
|
||||
WHERE time <= FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(NOW())/(60*60))*(60*60))
|
||||
@ -727,7 +725,7 @@ class Statistics extends Base {
|
||||
// Initilize array
|
||||
for ($i = 0; $i < 24; $i++) $aData[($iStartHour + $i) % 24] = 0;
|
||||
// Fill data
|
||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $row['hashrate'];
|
||||
while ($row = $result->fetch_assoc()) $aData[$row['hour']] += (int) $this->coin->calcHashrate($row['shares'], 3600);
|
||||
return $this->memcache->setCache(__FUNCTION__, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
@ -788,17 +786,19 @@ class Statistics extends Base {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($data = $this->memcache->get(__FUNCTION__ . $hour)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(COUNT(id), 0) as count,
|
||||
SELECT
|
||||
IFNULL(COUNT(id), 0) as count,
|
||||
IFNULL(AVG(difficulty), 0) as average,
|
||||
IFNULL(ROUND(SUM((POW(2, ( 32 - " . $this->config['target_bits'] . " )) * difficulty) / POW(2, (" . $this->config['difficulty'] . " -16))), 0), 0) AS expected,
|
||||
IFNULL(ROUND(SUM(shares)), 0) as shares,
|
||||
IFNULL(SUM(amount), 0) as rewards
|
||||
IFNULL(SUM(amount), 0) as rewards
|
||||
FROM " . $this->block->getTableName() . "
|
||||
WHERE FROM_UNIXTIME(time) > DATE_SUB(now(), INTERVAL ? HOUR)
|
||||
AND confirmations >= 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $hour) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $this->memcache->setCache(__FUNCTION__ . $hour, $result->fetch_assoc());
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $hour) && $stmt->execute() && $result = $stmt->get_result()) {
|
||||
$aData = $result->fetch_assoc();
|
||||
$aData['expected'] = $this->coin->calcEstaimtedShares($aData['average']);
|
||||
return $this->memcache->setCache(__FUNCTION__ . $hour, $aData);
|
||||
}
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
@ -808,7 +808,7 @@ class Statistics extends Base {
|
||||
* @return shares integer Share count
|
||||
**/
|
||||
public function getEstimatedShares($dDiff) {
|
||||
return round((POW(2, (32 - $this->config['target_bits'])) * $dDiff) / pow(2, ($this->config['difficulty'] - 16)));
|
||||
return $this->coin->calcEstaimtedShares($dDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -829,7 +829,7 @@ class Statistics extends Base {
|
||||
return $this->memcache->setCache(__FUNCTION__, $this->config['cointarget']);
|
||||
}
|
||||
|
||||
return $this->memcache->setCache(__FUNCTION__, pow(2, 32) * $dDifficulty / $dNetworkHashrate);
|
||||
return $this->memcache->setCache(__FUNCTION__, $this->coin->calcNetworkExpectedTimePerBlock($dDifficulty, $dNetworkHashrate));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -841,11 +841,13 @@ class Statistics extends Base {
|
||||
|
||||
if ($this->bitcoin->can_connect() === true) {
|
||||
$dDifficulty = $this->bitcoin->getdifficulty();
|
||||
$dNetworkHashrate = $this->bitcoin->getnetworkhashps();
|
||||
} else {
|
||||
$dDifficulty = 1;
|
||||
$dNetworkHashrate = 1;
|
||||
}
|
||||
|
||||
return $this->memcache->setCache(__FUNCTION__, round($dDifficulty * $this->config['cointarget'] / $this->getNetworkExpectedTimePerBlock(), 8));
|
||||
return $this->memcache->setCache(__FUNCTION__, $this->coin->calcExpectedNextDifficulty($dDifficulty, $dNetworkHashrate));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -890,7 +892,7 @@ class Statistics extends Base {
|
||||
$pps_reward = $this->config['pps']['reward']['default'];
|
||||
}
|
||||
}
|
||||
return round($pps_reward / (pow(2, $this->config['target_bits']) * $dDifficulty), 12);
|
||||
return round($this->coin->calcPPSValue($pps_reward, $dDifficulty), 12);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -922,5 +924,5 @@ $statistics->setMemcache($memcache);
|
||||
$statistics->setConfig($config);
|
||||
$statistics->setBitcoin($bitcoin);
|
||||
$statistics->setErrorCodes($aErrorCodes);
|
||||
|
||||
$statistics->setCoin($coin);
|
||||
?>
|
||||
|
||||
@ -31,6 +31,23 @@ class Template extends Base {
|
||||
return $aThemes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all available designs
|
||||
* Read css files from css/design folder
|
||||
*
|
||||
* @return array - list of available designs
|
||||
*/
|
||||
public function getDesigns() {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$aTmpDesigns = glob(BASEPATH . 'site_assets/' . THEME . '/css/design/*.css');
|
||||
$aDesigns = array();
|
||||
$aDesigns['default'] = 'default';
|
||||
foreach ($aTmpDesigns as $filename) {
|
||||
if (basename($filename) != '.' && basename($filename) != '..') $aDesigns[basename($filename, ".css")] = basename($filename, ".css");
|
||||
}
|
||||
return $aDesigns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached getActiveTemplates method
|
||||
*
|
||||
|
||||
@ -55,6 +55,10 @@ class Tools extends Base {
|
||||
return 'btce';
|
||||
} else if (preg_match('/cryptsy.com/', $url)) {
|
||||
return 'cryptsy';
|
||||
} else if (preg_match('/cryptorush.in/', $url)) {
|
||||
return 'cryptorush';
|
||||
} else if (preg_match('/mintpal.com/', $url)) {
|
||||
return 'mintpal';
|
||||
}
|
||||
$this->setErrorMessage("API URL unknown");
|
||||
return false;
|
||||
@ -84,6 +88,12 @@ class Tools extends Base {
|
||||
case 'cryptsy':
|
||||
return @$aData['return']['markets'][$strCurrency]['lasttradeprice'];
|
||||
break;
|
||||
case 'cryptorush':
|
||||
return @$aData["$strCurrency/" . $this->config['price']['currency']]['last_trade'];
|
||||
break;
|
||||
case 'mintpal':
|
||||
return @$aData['0']['last_price'];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$this->setErrorMessage("Got an invalid response from ticker API");
|
||||
|
||||
@ -70,8 +70,8 @@ class Transaction extends Base {
|
||||
$sql = "
|
||||
SELECT
|
||||
SUM(t.amount) AS total, t.type AS type
|
||||
FROM transactions AS t
|
||||
LEFT OUTER JOIN blocks AS b
|
||||
FROM $this->table AS t
|
||||
LEFT OUTER JOIN " . $this->block->getTableName() . " AS b
|
||||
ON b.id = t.block_id
|
||||
WHERE ( b.confirmations > 0 OR b.id IS NULL )";
|
||||
if (!empty($account_id)) {
|
||||
@ -100,6 +100,65 @@ class Transaction extends Base {
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch a transaction summary by user with total amounts
|
||||
* @param account_id int Account ID, NULL for all
|
||||
* @return data array type and total
|
||||
**/
|
||||
public function getTransactionTypebyTime($account_id=NULL) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
if ($data = $this->memcache->get(__FUNCTION__)) return $data;
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT
|
||||
IFNULL(SUM(IF(t.type = 'Credit' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourCredit,
|
||||
IFNULL(SUM(IF(t.type = 'Bonus' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourBonus,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_MP' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourDebitMP,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_AP' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourDebitAP,
|
||||
IFNULL(SUM(IF(t.type = 'TXFee' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourTXFee,
|
||||
IFNULL(SUM(IF(t.type = 'Fee' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourFee,
|
||||
IFNULL(SUM(IF(t.type = 'Donation' AND timestamp >= DATE_SUB(now(), INTERVAL 3600 SECOND), t.amount, 0)), 0) AS 1HourDonation,
|
||||
|
||||
IFNULL(SUM(IF(t.type = 'Credit' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourCredit,
|
||||
IFNULL(SUM(IF(t.type = 'Bonus' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourBonus,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_MP' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourDebitMP,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_AP' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourDebitAP,
|
||||
IFNULL(SUM(IF(t.type = 'TXFee' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourTXFee,
|
||||
IFNULL(SUM(IF(t.type = 'Fee' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourFee,
|
||||
IFNULL(SUM(IF(t.type = 'Donation' AND timestamp >= DATE_SUB(now(), INTERVAL 86400 SECOND), t.amount, 0)), 0) AS 24HourDonation,
|
||||
|
||||
IFNULL(SUM(IF(t.type = 'Credit' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekCredit,
|
||||
IFNULL(SUM(IF(t.type = 'Bonus' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekBonus,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_MP' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekDebitMP,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_AP' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekDebitAP,
|
||||
IFNULL(SUM(IF(t.type = 'TXFee' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekTXFee,
|
||||
IFNULL(SUM(IF(t.type = 'Fee' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekFee,
|
||||
IFNULL(SUM(IF(t.type = 'Donation' AND timestamp >= DATE_SUB(now(), INTERVAL 604800 SECOND), t.amount, 0)), 0) AS 1WeekDonation,
|
||||
|
||||
IFNULL(SUM(IF(t.type = 'Credit' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthCredit,
|
||||
IFNULL(SUM(IF(t.type = 'Bonus' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthBonus,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_MP' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthDebitMP,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_AP' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthDebitAP,
|
||||
IFNULL(SUM(IF(t.type = 'TXFee' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthTXFee,
|
||||
IFNULL(SUM(IF(t.type = 'Fee' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthFee,
|
||||
IFNULL(SUM(IF(t.type = 'Donation' AND timestamp >= DATE_SUB(now(), INTERVAL 2419200 SECOND), t.amount, 0)), 0) AS 1MonthDonation,
|
||||
|
||||
IFNULL(SUM(IF(t.type = 'Credit' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearCredit,
|
||||
IFNULL(SUM(IF(t.type = 'Bonus' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearBonus,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_MP' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearDebitMP,
|
||||
IFNULL(SUM(IF(t.type = 'Debit_AP' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearDebitAP,
|
||||
IFNULL(SUM(IF(t.type = 'TXFee' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearTXFee,
|
||||
IFNULL(SUM(IF(t.type = 'Fee' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearFee,
|
||||
IFNULL(SUM(IF(t.type = 'Donation' AND timestamp >= DATE_SUB(now(), INTERVAL 31536000 SECOND), t.amount, 0)), 0) AS 1YearDonation
|
||||
FROM $this->table AS t
|
||||
LEFT OUTER JOIN " . $this->block->getTableName() . " AS b ON b.id = t.block_id
|
||||
WHERE
|
||||
t.account_id = ? AND (b.confirmations > 0 OR b.id IS NULL)");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param("i", $account_id) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $this->memcache->setCache(__FUNCTION__ . $account_id, $result->fetch_assoc(), 60);
|
||||
return $this->sqlError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all transactions from start for account_id
|
||||
* @param start int Starting point, id of transaction
|
||||
@ -211,7 +270,7 @@ class Transaction extends Base {
|
||||
FROM $this->table AS t
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON t.account_id = a.id
|
||||
LEFT JOIN blocks AS b
|
||||
LEFT JOIN " . $this->block->getTableName() . " AS b
|
||||
ON t.block_id = b.id
|
||||
WHERE
|
||||
(
|
||||
@ -306,9 +365,9 @@ class Transaction extends Base {
|
||||
), 0
|
||||
) AS confirmed
|
||||
FROM $this->table AS t
|
||||
LEFT JOIN blocks AS b
|
||||
LEFT JOIN " . $this->block->getTableName() . " AS b
|
||||
ON t.block_id = b.id
|
||||
LEFT JOIN accounts AS a
|
||||
LEFT JOIN " . $this->user->getTableName() . " AS a
|
||||
ON t.account_id = a.id
|
||||
WHERE t.archived = 0 AND a.ap_threshold > 0 AND a.coin_address IS NOT NULL AND a.coin_address != ''
|
||||
GROUP BY t.account_id
|
||||
|
||||
@ -192,6 +192,11 @@ class User extends Base {
|
||||
return false;
|
||||
}
|
||||
if ($this->checkUserPassword($username, $password)) {
|
||||
// delete notification cookies
|
||||
setcookie("motd-box", "", time()-3600);
|
||||
setcookie("lastlogin-box", "", time()-3600);
|
||||
setcookie("backend-box", "", time()-3600);
|
||||
// rest of login process
|
||||
$uid = $this->getUserId($username);
|
||||
$lastLoginTime = $this->getLastLogin($uid);
|
||||
$this->updateLoginTimestamp($uid);
|
||||
@ -347,7 +352,7 @@ class User extends Base {
|
||||
**/
|
||||
public function existsCoinAddress($address) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
return $this->getSingle($address, 'coin_address', 'coin_address') === $address;
|
||||
return $this->getSingle($address, 'coin_address', 'coin_address', 's') === $address;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -624,15 +629,12 @@ class User extends Base {
|
||||
// Unset all of the session variables
|
||||
$_SESSION = array();
|
||||
// As we're killing the sesison, also kill the cookie!
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"]);
|
||||
}
|
||||
setcookie(session_name(), '', time() - 42000);
|
||||
// Destroy the session.
|
||||
session_destroy();
|
||||
// Enforce generation of a new Session ID and delete the old
|
||||
session_regenerate_id(true);
|
||||
|
||||
|
||||
// Enforce a page reload and point towards login with referrer included, if supplied
|
||||
$port = ($_SERVER["SERVER_PORT"] == "80" || $_SERVER["SERVER_PORT"] == "443") ? "" : (":".$_SERVER["SERVER_PORT"]);
|
||||
$pushto = $_SERVER['SCRIPT_NAME'].'?page=login';
|
||||
@ -866,7 +868,7 @@ class User extends Base {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
// Fetch the users mail address
|
||||
if (empty($username)) {
|
||||
$this->serErrorMessage("Username must not be empty");
|
||||
$this->setErrorMessage("Username must not be empty");
|
||||
return false;
|
||||
}
|
||||
if (filter_var($username, FILTER_VALIDATE_EMAIL)) {
|
||||
@ -926,23 +928,28 @@ public function isAuthenticated($logout=true) {
|
||||
|
||||
/**
|
||||
* Convenience function to get IP address, no params is the same as REMOTE_ADDR
|
||||
* @param trustremote bool must be FALSE to checkclient or checkforwarded
|
||||
* @param trustremote bool must be FALSE to checkcloudflare, checkclient or checkforwarded
|
||||
* @param checkcloudflare bool check HTTP_CF_CONNECTING_IP for a valid ip first
|
||||
* @param checkclient bool check HTTP_CLIENT_IP for a valid ip first
|
||||
* @param checkforwarded bool check HTTP_X_FORWARDED_FOR for a valid ip first
|
||||
* @return string IP address
|
||||
*/
|
||||
public function getCurrentIP($trustremote=false, $checkclient=false, $checkforwarded=true) {
|
||||
public function getCurrentIP($trustremote=false, $checkcloudflare=true, $checkclient=false, $checkforwarded=true) {
|
||||
$cf = (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : false;
|
||||
$client = (isset($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : false;
|
||||
$fwd = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : false;
|
||||
$remote = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : @$_SERVER['REMOTE_ADDR'];
|
||||
// shared internet
|
||||
if (filter_var($client, FILTER_VALIDATE_IP) && !$trustremote && $checkclient) {
|
||||
if (!$trustremote && $checkcloudflare && filter_var($cf, FILTER_VALIDATE_IP)) {
|
||||
// cloudflare
|
||||
return $cf;
|
||||
} else if (!$trustremote && $checkclient && filter_var($client, FILTER_VALIDATE_IP)) {
|
||||
return $client;
|
||||
} else if (strpos($fwd, ',') !== false && !$trustremote && $checkforwarded) {
|
||||
} else if (!$trustremote && $checkforwarded && strpos($fwd, ',') !== false) {
|
||||
// multiple proxies
|
||||
$ips = explode(',', $fwd);
|
||||
return $ips[0];
|
||||
} else if (filter_var($fwd, FILTER_VALIDATE_IP) && !$trustremote && $checkforwarded) {
|
||||
} else if (!$trustremote && $checkforwarded && filter_var($fwd, FILTER_VALIDATE_IP)) {
|
||||
// single
|
||||
return $fwd;
|
||||
} else {
|
||||
|
||||
@ -74,14 +74,14 @@ class Worker extends Base {
|
||||
( SELECT COUNT(id) FROM " . $this->share->getArchiveTableName() . " WHERE username = w.username AND time > DATE_SUB(now(), INTERVAL ? SECOND)) AS count_all_archive,
|
||||
(
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->coin->getTargetBits() . ") / ? / 1000), 0), 0) AS hashrate
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE
|
||||
username = w.username
|
||||
AND time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
) + (
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->coin->getTargetBits() . ") / ? / 1000), 0), 0) AS hashrate
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE
|
||||
username = w.username
|
||||
@ -117,14 +117,14 @@ class Worker extends Base {
|
||||
( SELECT COUNT(id) FROM " . $this->share->getArchiveTableName() . " WHERE username = w.username AND time > DATE_SUB(now(), INTERVAL ? SECOND)) AS count_all_archive,
|
||||
(
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->coin->getTargetBits() . ") / ? / 1000), 0), 0) AS hashrate
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE
|
||||
username = w.username
|
||||
AND time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
) + (
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->coin->getTargetBits() . ") / ? / 1000), 0), 0) AS hashrate
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE
|
||||
username = w.username
|
||||
@ -158,14 +158,14 @@ class Worker extends Base {
|
||||
IFNULL(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty), 0) AS difficulty,
|
||||
(
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->coin->getTargetBits() . ") / ? / 1000), 0), 0) AS hashrate
|
||||
FROM " . $this->share->getTableName() . "
|
||||
WHERE
|
||||
username = w.username
|
||||
AND time > DATE_SUB(now(), INTERVAL ? SECOND)
|
||||
) + (
|
||||
SELECT
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->config['target_bits'] . ") / ? / 1000), 0), 0) AS hashrate
|
||||
IFNULL(IF(our_result='Y', ROUND(SUM(IF(difficulty=0, pow(2, (" . $this->config['difficulty'] . " - 16)), difficulty)) * POW(2, " . $this->coin->getTargetBits() . ") / ? / 1000), 0), 0) AS hashrate
|
||||
FROM " . $this->share->getArchiveTableName() . "
|
||||
WHERE
|
||||
username = w.username
|
||||
@ -272,5 +272,5 @@ $worker->setShare($share);
|
||||
$worker->setConfig($config);
|
||||
$worker->setUser($user);
|
||||
$worker->setErrorCodes($aErrorCodes);
|
||||
|
||||
$worker->setCoin($coin);
|
||||
?>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
|
||||
|
||||
$aThemes = $template->getThemes();
|
||||
$aDesigns = $template->getDesigns();
|
||||
|
||||
// Load the settings available in this system
|
||||
$aSettings['website'][] = array(
|
||||
@ -49,16 +50,30 @@ $aSettings['website'][] = array(
|
||||
$aSettings['website'][] = array(
|
||||
'display' => 'Website theme', 'type' => 'select',
|
||||
'options' => $aThemes,
|
||||
'default' => 'mpos',
|
||||
'default' => 'bootstrap',
|
||||
'name' => 'website_theme', 'value' => $setting->getValue('website_theme'),
|
||||
'tooltip' => 'The default theme used on your pool.'
|
||||
);
|
||||
$aSettings['website'][] = array(
|
||||
'display' => 'Website mobile theme', 'type' => 'select',
|
||||
'options' => $aThemes,
|
||||
'default' => 'mobile',
|
||||
'name' => 'website_mobile_theme', 'value' => $setting->getValue('website_mobile_theme'),
|
||||
'tooltip' => 'The mobile theme used for your pool.'
|
||||
'display' => 'Website Design', 'type' => 'select',
|
||||
'options' => $aDesigns,
|
||||
'default' => 'default',
|
||||
'name' => 'website_design', 'value' => $setting->getValue('website_design'),
|
||||
'tooltip' => 'The default design used on your pool.'
|
||||
);
|
||||
$aSettings['website'][] = array(
|
||||
'display' => 'Website News Style', 'type' => 'select',
|
||||
'options' => array( 0 => 'Show all news in one Page', 1 => 'Show Responsive News Table' ),
|
||||
'default' => 0,
|
||||
'name' => 'website_news_style', 'value' => $setting->getValue('website_news_style'),
|
||||
'tooltip' => 'How News are displayed on Main Page.'
|
||||
);
|
||||
$aSettings['website'][] = array(
|
||||
'display' => 'Auto Hide Notifications', 'type' => 'select',
|
||||
'options' => array( 0 => 'Notifications always visible', 1 => 'Hide Notifications automatically' ),
|
||||
'default' => 0,
|
||||
'name' => 'website_notification_autohide', 'value' => $setting->getValue('website_notification_autohide'),
|
||||
'tooltip' => 'Hides Notifications after 5 seconds.'
|
||||
);
|
||||
$aSettings['blockchain'][] = array(
|
||||
'display' => 'Disable Blockexplorer', 'type' => 'select',
|
||||
@ -257,6 +272,20 @@ $aSettings['acl'][] = array(
|
||||
'name' => 'acl_chat_page', 'value' => $setting->getValue('acl_chat_page'),
|
||||
'tooltip' => 'Make the chat page private (users only) or public.'
|
||||
);
|
||||
$aSettings['acl'][] = array(
|
||||
'display' => 'MOOT Forum Page', 'type' => 'select',
|
||||
'options' => array( 0 => 'Private', 1 => 'Public', 2 => 'Disabled' ),
|
||||
'default' => 2,
|
||||
'name' => 'acl_moot_forum', 'value' => $setting->getValue('acl_moot_forum'),
|
||||
'tooltip' => 'Make the forum page private (users only) or public.'
|
||||
);
|
||||
$aSettings['acl'][] = array(
|
||||
'display' => 'QRCode', 'type' => 'select',
|
||||
'options' => array( 0 => 'Enabled', 1 => 'Disabled' ),
|
||||
'default' => 0,
|
||||
'name' => 'acl_qrcode', 'value' => $setting->getValue('acl_qrcode'),
|
||||
'tooltip' => 'Hide or Show the QRCode Page.'
|
||||
);
|
||||
$aSettings['system'][] = array(
|
||||
'display' => 'E-mail address for system error notifications', 'type' => 'text',
|
||||
'size' => 25,
|
||||
@ -355,6 +384,13 @@ $aSettings['system'][] = array(
|
||||
'name' => 'system_irc_chat', 'value' => $setting->getValue('system_irc_chat'),
|
||||
'tooltip' => 'Your IRC support channel name.'
|
||||
);
|
||||
$aSettings['system'][] = array(
|
||||
'display' => 'Moot Forum Channel', 'type' => 'text',
|
||||
'size' => 25,
|
||||
'default' => 'lazypoolop',
|
||||
'name' => 'system_moot_forum', 'value' => $setting->getValue('system_moot_forum'),
|
||||
'tooltip' => 'Your MOOT support forum name.'
|
||||
);
|
||||
$aSettings['recaptcha'][] = array(
|
||||
'display' => 'Enable re-Captcha', 'type' => 'select',
|
||||
'options' => array( 0 => 'No', 1 => 'Yes' ),
|
||||
@ -425,3 +461,32 @@ $aSettings['notifications'][] = array(
|
||||
'name' => 'notifications_disable_block', 'value' => $setting->getValue('notifications_disable_block'),
|
||||
'tooltip' => 'Enable/Disable block notifications globally. Will remove the user option too.'
|
||||
);
|
||||
$aSettings['notifications'][] = array(
|
||||
'display' => 'Disable IDLE Worker Notifications', 'type' => 'select',
|
||||
'options' => array( 0 => 'No', 1 => 'Yes'),
|
||||
'default' => 0,
|
||||
'name' => 'notifications_disable_idle_worker', 'value' => $setting->getValue('notifications_disable_idle_worker'),
|
||||
'tooltip' => 'Enable/Disable IDLE worker notifications globally. Will remove the user option too.'
|
||||
);
|
||||
$aSettings['notifications'][] = array(
|
||||
'display' => 'Disable Pool Newsletter', 'type' => 'select',
|
||||
'options' => array( 0 => 'No', 1 => 'Yes'),
|
||||
'default' => 0,
|
||||
'name' => 'notifications_disable_pool_newsletter', 'value' => $setting->getValue('notifications_disable_pool_newsletter'),
|
||||
'tooltip' => 'Enable/Disable pool newsletter globally. Will remove the user option too.'
|
||||
);
|
||||
$aSettings['pools'][] = array(
|
||||
'display' => 'Enable Pool Navigation', 'type' => 'select',
|
||||
'options' => array( 0 => 'No', 1 => 'Yes' ),
|
||||
'default' => 0,
|
||||
'name' => 'poolnav_enabled', 'value' => $setting->getValue('poolnav_enabled'),
|
||||
'tooltip' => 'Enable or Disable Pool Navigation for multiple Pools in Header.'
|
||||
);
|
||||
$aSettings['pools'][] = array(
|
||||
'display' => 'Pools for Pool Navigation', 'type' => 'textarea',
|
||||
'size' => 20,
|
||||
'height' => 12,
|
||||
'default' => 'Pool Name|Pool URL',
|
||||
'name' => 'poolnav_pools', 'value' => $setting->getValue('poolnav_pools'),
|
||||
'tooltip' => '.'
|
||||
);
|
||||
|
||||
@ -35,7 +35,7 @@ $aErrorCodes['E0030'] = 'Unable to fetch a valid token for this invitation';
|
||||
$aErrorCodes['E0031'] = 'Failed to send e-mail via mail() function';
|
||||
$aErrorCodes['E0032'] = 'Failed to run API call: %s';
|
||||
$aErrorCodes['E0033'] = 'Failed to store uptime status: %s';
|
||||
$aErrorCodes['E0034'] = 'Subjcet may only contain alphanumeric characters';
|
||||
$aErrorCodes['E0034'] = 'Subject may only contain alphanumeric characters';
|
||||
$aErrorCodes['E0035'] = 'Failed to add news record';
|
||||
$aErrorCodes['E0036'] = 'Failed to delete news record';
|
||||
$aErrorCodes['E0037'] = 'Failed to update news record';
|
||||
@ -77,4 +77,5 @@ $aErrorCodes['E0078'] = 'RPC method did not return 200 OK';
|
||||
$aErrorCodes['E0079'] = 'Wallet does not cover payouts total amount';
|
||||
$aErrorCodes['E0080'] = 'No new unaccounted shares since last run';
|
||||
$aErrorCodes['E0081'] = 'Failed to insert new block into database';
|
||||
$aErrorCodes['E0082'] = 'Block does not supply any usable confirmation information';
|
||||
?>
|
||||
|
||||
@ -29,6 +29,13 @@ $config['SALTY'] = 'THISSHOULDALSOBERRAANNDDOOM';
|
||||
**/
|
||||
$config['algorithm'] = 'scrypt';
|
||||
|
||||
/**
|
||||
* Getbalance API Calls
|
||||
* System used for getting actual Balance from Wallet
|
||||
* https://github.com/MPOS/php-mpos/wiki/Config-Setup#getbalance-api-calls
|
||||
**/
|
||||
$config['getbalancewithunconfirmed'] = true;
|
||||
|
||||
/**
|
||||
* Database configuration
|
||||
* MySQL database configuration
|
||||
@ -50,6 +57,21 @@ $config['wallet']['host'] = 'localhost:19334';
|
||||
$config['wallet']['username'] = 'testnet';
|
||||
$config['wallet']['password'] = 'testnet';
|
||||
|
||||
/**
|
||||
* Swiftmailer configuration
|
||||
* Configure your way to send mails
|
||||
* https://github.com/MPOS/php-mpos/wiki/Config-Setup#wiki-swiftmailer
|
||||
**/
|
||||
$config['swiftmailer']['type'] = 'sendmail';
|
||||
$config['swiftmailer']['sendmail']['path'] = '/usr/sbin/sendmail';
|
||||
$config['swiftmailer']['sendmail']['options'] = '-bs';
|
||||
$config['switfmailer']['smtp']['host'] = 'your.mail-relay.com';
|
||||
$config['switfmailer']['smtp']['port'] = '587';
|
||||
$config['switfmailer']['smtp']['encryption'] = 'tls';
|
||||
$config['switfmailer']['smtp']['username'] = '';
|
||||
$config['switfmailer']['smtp']['password'] = '';
|
||||
$config['switfmailer']['smtp']['throttle'] = 100;
|
||||
|
||||
/**
|
||||
* Getting Started Config
|
||||
* Shown to users in the 'Getting Started' section
|
||||
@ -65,6 +87,7 @@ $config['gettingstarted']['stratumport'] = '3333';
|
||||
* Fetch exchange rates via an API
|
||||
* https://github.com/MPOS/php-mpos/wiki/Config-Setup#wiki-ticker-api
|
||||
**/
|
||||
$config['price']['enabled'] = false;
|
||||
$config['price']['url'] = 'https://btc-e.com';
|
||||
$config['price']['target'] = '/api/2/ltc_usd/ticker';
|
||||
$config['price']['currency'] = 'USD';
|
||||
@ -77,6 +100,13 @@ $config['price']['currency'] = 'USD';
|
||||
$config['ap_threshold']['min'] = 1;
|
||||
$config['ap_threshold']['max'] = 250;
|
||||
|
||||
/**
|
||||
* Minimum manual Payout Threshold
|
||||
* Minimum manual payout amount
|
||||
* https://github.com/MPOS/php-mpos/wiki/Config-Setup#wiki-manual-payout-threshold
|
||||
**/
|
||||
$config['mp_threshold'] = 1;
|
||||
|
||||
/**
|
||||
* Donation thresholds
|
||||
* Minimum donation amount in percent
|
||||
@ -121,12 +151,14 @@ $config['txfee_auto'] = 0.1;
|
||||
$config['txfee_manual'] = 0.1;
|
||||
|
||||
/**
|
||||
* Block Bonus
|
||||
* Bonus in coins of block bonus
|
||||
* Block & Pool Bonus
|
||||
* Bonus coins for blockfinder or a pool bonus for everyone
|
||||
* https://github.com/MPOS/php-mpos/wiki/Config-Setup#wiki-block-bonus
|
||||
* https://github.com/MPOS/php-mpos/wiki/Config-Setup#wiki-pool-bonus
|
||||
*/
|
||||
$config['block_bonus'] = 0;
|
||||
|
||||
$config['pool_bonus'] = 0;
|
||||
$config['pool_bonus_type'] = 'payout';
|
||||
|
||||
/**
|
||||
* Payout System
|
||||
|
||||
@ -2,16 +2,16 @@
|
||||
|
||||
// Small helper array that may be used on some page controllers to
|
||||
// fetch the crons we wish to monitor
|
||||
$aMonitorCrons = array('statistics','payouts','tables_cleanup','blockupdate','findblock','notifications','tickerupdate');
|
||||
|
||||
switch ($config['payout_system']) {
|
||||
case 'pplns':
|
||||
$aMonitorCrons[] = $config['payout_system'] . '_payout';
|
||||
break;
|
||||
case 'pps':
|
||||
$aMonitorCrons[] = $config['payout_system'] . '_payout';
|
||||
break;
|
||||
case 'prop':
|
||||
$aMonitorCrons[] = 'proportional_payout';
|
||||
break;
|
||||
case 'pplns':
|
||||
$sPayoutSystem = $config['payout_system'] . '_payout';
|
||||
break;
|
||||
case 'pps':
|
||||
$sPayoutSystem = $config['payout_system'] . '_payout';
|
||||
break;
|
||||
case 'prop':
|
||||
$sPayoutSystem = 'proportional_payout';
|
||||
break;
|
||||
}
|
||||
|
||||
$aMonitorCrons = array('statistics','tickerupdate','notifications','tables_cleanup','findblock',$sPayoutSystem,'blockupdate','payouts');
|
||||
|
||||
@ -1,814 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* MIT License
|
||||
* ===========
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*
|
||||
* @author Serban Ghita <serbanghita@gmail.com>
|
||||
* Victor Stanciu <vic.stanciu@gmail.com> (until v. 1.0)
|
||||
* @license MIT License https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt
|
||||
* @link Official page: http://mobiledetect.net
|
||||
* GitHub Repository: https://github.com/serbanghita/Mobile-Detect
|
||||
* Google Code Old Page: http://code.google.com/p/php-mobile-detect/
|
||||
* @version 2.6.2
|
||||
*/
|
||||
|
||||
class Mobile_Detect {
|
||||
|
||||
protected $scriptVersion = '2.6.2';
|
||||
|
||||
// External info.
|
||||
protected $userAgent = null;
|
||||
protected $httpHeaders;
|
||||
|
||||
// Arrays holding all detection rules.
|
||||
protected $mobileDetectionRules = null;
|
||||
protected $mobileDetectionRulesExtended = null;
|
||||
// Type of detection to use.
|
||||
protected $detectionType = 'mobile'; // mobile, extended @todo: refactor this.
|
||||
|
||||
// List of mobile devices (phones)
|
||||
protected $phoneDevices = array(
|
||||
'iPhone' => '\biPhone.*Mobile|\biPod|\biTunes',
|
||||
'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
|
||||
'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b',
|
||||
'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile',
|
||||
// @todo: Is 'Dell Streak' a tablet or a phone? ;)
|
||||
'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b',
|
||||
'Motorola' => 'Motorola|\bDroid\b.*Build|DROIDX|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT909|XT910|XT912|XT928',
|
||||
'Samsung' => 'Samsung|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|SCH-I535',
|
||||
'LG' => '\bLG\b;|(LG|LG-)?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999)',
|
||||
'Sony' => 'sony|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i',
|
||||
'Asus' => 'Asus.*Galaxy',
|
||||
'Palm' => 'PalmSource|Palm', // avantgo|blazer|elaine|hiptop|plucker|xiino ; @todo - complete the regex.
|
||||
'Vertu' => 'Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature', // Just for fun ;)
|
||||
// @ref: http://www.pantech.co.kr/en/prod/prodList.do?gbrand=VEGA (PANTECH)
|
||||
// Most of the VEGA devices are legacy. PANTECH seem to be newer devices based on Android.
|
||||
'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790',
|
||||
// @ref: http://www.fly-phone.com/devices/smartphones/ ; Included only smartphones.
|
||||
'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
|
||||
// Added simvalley mobile just for fun. They have some interesting devices.
|
||||
// @ref: http://www.simvalley.fr/telephonie---gps-_22_telephonie-mobile_telephones_.html
|
||||
'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b',
|
||||
// @Tapatalk is a mobile app; @ref: http://support.tapatalk.com/threads/smf-2-0-2-os-and-browser-detection-plugin-and-tapatalk.15565/#post-79039
|
||||
'GenericPhone' => 'Tapatalk|PDA;|PPC;|SAGEM|mmp|pocket|psp|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|wap|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser|LG-P500'
|
||||
);
|
||||
// List of tablet devices.
|
||||
protected $tabletDevices = array(
|
||||
'iPad' => 'iPad|iPad.*Mobile', // @todo: check for mobile friendly emails topic.
|
||||
'NexusTablet' => '^.*Android.*Nexus(((?:(?!Mobile))|(?:(\s(7|10).+))).)*$',
|
||||
'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925',
|
||||
// @reference: http://www.labnol.org/software/kindle-user-agent-string/20378/
|
||||
'Kindle' => 'Kindle|Silk.*Accelerated',
|
||||
// Only the Surface tablets with Windows RT are considered mobile.
|
||||
// @ref: http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
|
||||
'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;',
|
||||
'AsusTablet' => 'Transformer|TF101',
|
||||
'BlackBerryTablet' => 'PlayBook|RIM Tablet',
|
||||
'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200',
|
||||
'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
|
||||
'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|LogicPD Zoom2',
|
||||
// @ref: http://www.acer.ro/ac/ro/RO/content/drivers
|
||||
// @ref: http://www.packardbell.co.uk/pb/en/GB/content/download (Packard Bell is part of Acer)
|
||||
'AcerTablet' => 'Android.*\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71)\b',
|
||||
// @ref: http://eu.computers.toshiba-europe.com/innovation/family/Tablets/1098744/banner_id/tablet_footerlink/
|
||||
// @ref: http://us.toshiba.com/tablets/tablet-finder
|
||||
// @ref: http://www.toshiba.co.jp/regza/tablet/
|
||||
'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
|
||||
// @ref: http://www.nttdocomo.co.jp/english/service/developer/smart_phone/technical_info/spec/index.html
|
||||
'LGTablet' => '\bL-06C|LG-V900|LG-V909\b',
|
||||
// Prestigio Tablets http://www.prestigio.com/support
|
||||
'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474',
|
||||
'YarvikTablet' => 'Android.*(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468)',
|
||||
'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
|
||||
'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT',
|
||||
// @reference: http://wiki.archosfans.com/index.php?title=Main_Page
|
||||
'ArchosTablet' => 'Android.*ARCHOS|\b101G9\b|\b80G9\b',
|
||||
// @reference: http://en.wikipedia.org/wiki/NOVO7
|
||||
'AinolTablet' => 'NOVO7|Novo7Aurora|Novo7Basic|NOVO7PALADIN',
|
||||
// @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER
|
||||
// @ref: Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser
|
||||
// @ref: http://www.sony.jp/support/tablet/
|
||||
'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT211|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201',
|
||||
// @ref: db + http://www.cube-tablet.com/buy-products.html
|
||||
'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
|
||||
// @ref: http://www.cobyusa.com/?p=pcat&pcat_id=3001
|
||||
'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
|
||||
// @ref: http://pdadb.net/index.php?m=pdalist&list=SMiT (NoName Chinese Tablets)
|
||||
// @ref: http://www.imp3.net/14/show.php?itemid=20454
|
||||
'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
|
||||
// @ref: http://www.rock-chips.com/index.php?do=prod&pid=2
|
||||
'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
|
||||
// @ref: http://www.telstra.com.au/home-phone/thub-2/
|
||||
'TelstraTablet' => 'T-Hub2',
|
||||
// @ref: http://www.fly-phone.com/devices/tablets/ ; http://www.fly-phone.com/service/
|
||||
'FlyTablet' => 'IQ310|Fly Vision',
|
||||
// @ref: http://www.bqreaders.com/gb/tablets-prices-sale.html
|
||||
'bqTablet' => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)',
|
||||
// @ref: http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290
|
||||
// @ref: http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets)
|
||||
'HuaweiTablet' => 'MediaPad|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim',
|
||||
// Nec or Medias Tab
|
||||
'NecTablet' => '\bN-06D|\bN-08D',
|
||||
// Pantech Tablets: http://www.pantechusa.com/phones/
|
||||
'PantechTablet' => 'Pantech.*P4100',
|
||||
// Broncho Tablets: http://www.broncho.cn/ (hard to find)
|
||||
'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
|
||||
// @ref: http://versusuk.com/support.html
|
||||
'VersusTablet' => 'TOUCHPAD.*[78910]',
|
||||
// @ref: http://www.zync.in/index.php/our-products/tablet-phablets
|
||||
'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
|
||||
// @ref: http://www.positivoinformatica.com.br/www/pessoal/tablet-ypy/
|
||||
'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
|
||||
// @ref: https://www.nabitablet.com/
|
||||
'NabiTablet' => 'Android.*\bNabi',
|
||||
'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
|
||||
// French Danew Tablets http://www.danew.com/produits-tablette.php
|
||||
'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
|
||||
// Texet Tablets and Readers http://www.texet.ru/tablet/
|
||||
'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE',
|
||||
// @note: Avoid detecting 'PLAYSTATION 3' as mobile.
|
||||
'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
|
||||
// @ref: http://www.galapad.net/product.html
|
||||
'GalapadTablet' => 'Android.*\bG1\b',
|
||||
'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|ViewPad7|MID7015|BNTV250A|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|hp-tablet|rk30sdk',
|
||||
);
|
||||
// List of mobile Operating Systems.
|
||||
protected $operatingSystems = array(
|
||||
'AndroidOS' => 'Android',
|
||||
'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
|
||||
'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
|
||||
'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
|
||||
// @reference: http://en.wikipedia.org/wiki/Windows_Mobile
|
||||
'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
|
||||
// @reference: http://en.wikipedia.org/wiki/Windows_Phone
|
||||
// http://wifeng.cn/?r=blog&a=view&id=106
|
||||
// http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
|
||||
'WindowsPhoneOS' => 'Windows Phone OS|XBLWP7|ZuneWP7',
|
||||
'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
|
||||
// http://en.wikipedia.org/wiki/MeeGo
|
||||
// @todo: research MeeGo in UAs
|
||||
'MeeGoOS' => 'MeeGo',
|
||||
// http://en.wikipedia.org/wiki/Maemo
|
||||
// @todo: research Maemo in UAs
|
||||
'MaemoOS' => 'Maemo',
|
||||
'JavaOS' => 'J2ME/|Java/|\bMIDP\b|\bCLDC\b',
|
||||
'webOS' => 'webOS|hpwOS',
|
||||
'badaOS' => '\bBada\b',
|
||||
'BREWOS' => 'BREW',
|
||||
);
|
||||
// List of mobile User Agents.
|
||||
protected $userAgents = array(
|
||||
// @reference: https://developers.google.com/chrome/mobile/docs/user-agent
|
||||
'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
|
||||
'Dolfin' => '\bDolfin\b',
|
||||
'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+',
|
||||
'Skyfire' => 'Skyfire',
|
||||
'IE' => 'IEMobile|MSIEMobile',
|
||||
'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
|
||||
'Bolt' => 'bolt',
|
||||
'TeaShark' => 'teashark',
|
||||
'Blazer' => 'Blazer',
|
||||
// @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
|
||||
'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile',
|
||||
// @ref: http://en.wikipedia.org/wiki/Midori_(web_browser)
|
||||
//'Midori' => 'midori',
|
||||
'Tizen' => 'Tizen',
|
||||
'UCBrowser' => 'UC.*Browser|UCWEB',
|
||||
// @ref: https://github.com/serbanghita/Mobile-Detect/issues/7
|
||||
'DiigoBrowser' => 'DiigoBrowser',
|
||||
// http://www.puffinbrowser.com/index.php
|
||||
'Puffin' => 'Puffin',
|
||||
// @ref: http://mercury-browser.com/index.html
|
||||
'Mercury' => '\bMercury\b',
|
||||
// @reference: http://en.wikipedia.org/wiki/Minimo
|
||||
// http://en.wikipedia.org/wiki/Vision_Mobile_Browser
|
||||
'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision'
|
||||
);
|
||||
// Utilities.
|
||||
protected $utilities = array(
|
||||
// Experimental. When a mobile device wants to switch to 'Desktop Mode'.
|
||||
// @ref: http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
|
||||
// @ref: https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
|
||||
'DesktopMode' => 'WPDesktop',
|
||||
'TV' => 'SonyDTV115', // experimental
|
||||
'WebKit' => '(webkit)[ /]([\w.]+)',
|
||||
'Bot' => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit',
|
||||
'MobileBot' => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2',
|
||||
);
|
||||
// Properties list.
|
||||
// @reference: http://user-agent-string.info/list-of-ua#Mobile Browser
|
||||
const VER = '([\w._\+]+)';
|
||||
protected $properties = array(
|
||||
|
||||
// Build
|
||||
'Mobile' => 'Mobile/[VER]',
|
||||
'Build' => 'Build/[VER]',
|
||||
'Version' => 'Version/[VER]',
|
||||
'VendorID' => 'VendorID/[VER]',
|
||||
|
||||
// Devices
|
||||
'iPad' => 'iPad.*CPU[a-z ]+[VER]',
|
||||
'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
|
||||
'iPod' => 'iPod.*CPU[a-z ]+[VER]',
|
||||
//'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
|
||||
'Kindle' => 'Kindle/[VER]',
|
||||
|
||||
// Browser
|
||||
'Chrome' => array('Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]'),
|
||||
'Dolfin' => 'Dolfin/[VER]',
|
||||
// @reference: https://developer.mozilla.org/en-US/docs/User_Agent_Strings_Reference
|
||||
'Firefox' => 'Firefox/[VER]',
|
||||
'Fennec' => 'Fennec/[VER]',
|
||||
// @reference: http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
|
||||
'IE' => array('IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];'),
|
||||
// http://en.wikipedia.org/wiki/NetFront
|
||||
'NetFront' => 'NetFront/[VER]',
|
||||
'NokiaBrowser' => 'NokiaBrowser/[VER]',
|
||||
'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
|
||||
'UC Browser' => 'UC Browser[VER]',
|
||||
// @note: Safari 7534.48.3 is actually Version 5.1.
|
||||
// @note: On BlackBerry the Version is overwriten by the OS.
|
||||
'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
|
||||
'Skyfire' => 'Skyfire/[VER]',
|
||||
'Tizen' => 'Tizen/[VER]',
|
||||
'Webkit' => 'webkit[ /][VER]',
|
||||
|
||||
// Engine
|
||||
'Gecko' => 'Gecko/[VER]',
|
||||
'Trident' => 'Trident/[VER]',
|
||||
'Presto' => 'Presto/[VER]',
|
||||
|
||||
// OS
|
||||
'iOS' => ' \bOS\b [VER] ',
|
||||
'Android' => 'Android [VER]',
|
||||
'BlackBerry' => array('BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]'),
|
||||
'BREW' => 'BREW [VER]',
|
||||
'Java' => 'Java/[VER]',
|
||||
// @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
|
||||
// @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
|
||||
'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]'),
|
||||
'Windows Phone' => 'Windows Phone [VER]',
|
||||
'Windows CE' => 'Windows CE/[VER]',
|
||||
// http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
|
||||
'Windows NT' => 'Windows NT [VER]',
|
||||
'Symbian' => array('SymbianOS/[VER]', 'Symbian/[VER]'),
|
||||
'webOS' => array('webOS/[VER]', 'hpwOS/[VER];'),
|
||||
|
||||
|
||||
);
|
||||
|
||||
function __construct(){
|
||||
|
||||
$this->setHttpHeaders();
|
||||
$this->setUserAgent();
|
||||
|
||||
$this->setMobileDetectionRules();
|
||||
$this->setMobileDetectionRulesExtended();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current script version.
|
||||
* This is useful for the demo.php file,
|
||||
* so people can check on what version they are testing
|
||||
* for mobile devices.
|
||||
*/
|
||||
public function getScriptVersion(){
|
||||
|
||||
return $this->scriptVersion;
|
||||
|
||||
}
|
||||
|
||||
public function setHttpHeaders($httpHeaders = null){
|
||||
|
||||
if(!empty($httpHeaders)){
|
||||
$this->httpHeaders = $httpHeaders;
|
||||
} else {
|
||||
foreach($_SERVER as $key => $value){
|
||||
if(substr($key,0,5)=='HTTP_'){
|
||||
$this->httpHeaders[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getHttpHeaders(){
|
||||
|
||||
return $this->httpHeaders;
|
||||
|
||||
}
|
||||
|
||||
public function setUserAgent($userAgent = null){
|
||||
|
||||
if(!empty($userAgent)){
|
||||
$this->userAgent = $userAgent;
|
||||
} else {
|
||||
$this->userAgent = isset($this->httpHeaders['HTTP_USER_AGENT']) ? $this->httpHeaders['HTTP_USER_AGENT'] : null;
|
||||
|
||||
if(empty($this->userAgent)){
|
||||
$this->userAgent = isset($this->httpHeaders['HTTP_X_DEVICE_USER_AGENT']) ? $this->httpHeaders['HTTP_X_DEVICE_USER_AGENT'] : null;
|
||||
}
|
||||
// Header can occur on devices using Opera Mini (can expose the real device type). Let's concatenate it (we need this extra info in the regexes).
|
||||
if(!empty($this->httpHeaders['HTTP_X_OPERAMINI_PHONE_UA'])){
|
||||
$this->userAgent .= ' '.$this->httpHeaders['HTTP_X_OPERAMINI_PHONE_UA'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getUserAgent(){
|
||||
|
||||
return $this->userAgent;
|
||||
|
||||
}
|
||||
|
||||
function setDetectionType($type = null){
|
||||
|
||||
$this->detectionType = (!empty($type) ? $type : 'mobile');
|
||||
|
||||
}
|
||||
|
||||
public function getPhoneDevices(){
|
||||
|
||||
return $this->phoneDevices;
|
||||
|
||||
}
|
||||
|
||||
public function getTabletDevices(){
|
||||
|
||||
return $this->tabletDevices;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method sets the mobile detection rules.
|
||||
*
|
||||
* This method is used for the magic methods $detect->is*()
|
||||
*/
|
||||
public function setMobileDetectionRules(){
|
||||
// Merge all rules together.
|
||||
$this->mobileDetectionRules = array_merge(
|
||||
$this->phoneDevices,
|
||||
$this->tabletDevices,
|
||||
$this->operatingSystems,
|
||||
$this->userAgents
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method sets the mobile detection rules + utilities.
|
||||
* The reason this is separate is because utilities rules
|
||||
* don't necessary imply mobile.
|
||||
*
|
||||
* This method is used inside the new $detect->is('stuff') method.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMobileDetectionRulesExtended(){
|
||||
|
||||
// Merge all rules together.
|
||||
$this->mobileDetectionRulesExtended = array_merge(
|
||||
$this->phoneDevices,
|
||||
$this->tabletDevices,
|
||||
$this->operatingSystems,
|
||||
$this->userAgents,
|
||||
$this->utilities
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getRules()
|
||||
{
|
||||
|
||||
if($this->detectionType=='extended'){
|
||||
return $this->mobileDetectionRulesExtended;
|
||||
} else {
|
||||
return $this->mobileDetectionRules;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the HTTP headers for signs of mobile.
|
||||
* This is the fastest mobile check possible; it's used
|
||||
* inside isMobile() method.
|
||||
* @return boolean
|
||||
*/
|
||||
public function checkHttpHeadersForMobile(){
|
||||
|
||||
if(
|
||||
isset($this->httpHeaders['HTTP_ACCEPT']) &&
|
||||
(strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/x-obml2d') !== false || // Opera Mini; @reference: http://dev.opera.com/articles/view/opera-binary-markup-language/
|
||||
strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/vnd.rim.html') !== false || // BlackBerry devices.
|
||||
strpos($this->httpHeaders['HTTP_ACCEPT'], 'text/vnd.wap.wml') !== false ||
|
||||
strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/vnd.wap.xhtml+xml') !== false) ||
|
||||
isset($this->httpHeaders['HTTP_X_WAP_PROFILE']) || // @todo: validate
|
||||
isset($this->httpHeaders['HTTP_X_WAP_CLIENTID']) ||
|
||||
isset($this->httpHeaders['HTTP_WAP_CONNECTION']) ||
|
||||
isset($this->httpHeaders['HTTP_PROFILE']) ||
|
||||
isset($this->httpHeaders['HTTP_X_OPERAMINI_PHONE_UA']) || // Reported by Nokia devices (eg. C3)
|
||||
isset($this->httpHeaders['HTTP_X_NOKIA_IPADDRESS']) ||
|
||||
isset($this->httpHeaders['HTTP_X_NOKIA_GATEWAY_ID']) ||
|
||||
isset($this->httpHeaders['HTTP_X_ORANGE_ID']) ||
|
||||
isset($this->httpHeaders['HTTP_X_VODAFONE_3GPDPCONTEXT']) ||
|
||||
isset($this->httpHeaders['HTTP_X_HUAWEI_USERID']) ||
|
||||
isset($this->httpHeaders['HTTP_UA_OS']) || // Reported by Windows Smartphones.
|
||||
isset($this->httpHeaders['HTTP_X_MOBILE_GATEWAY']) || // Reported by Verizon, Vodafone proxy system.
|
||||
isset($this->httpHeaders['HTTP_X_ATT_DEVICEID']) || // Seend this on HTC Sensation. @ref: SensationXE_Beats_Z715e
|
||||
//HTTP_X_NETWORK_TYPE = WIFI
|
||||
( isset($this->httpHeaders['HTTP_UA_CPU']) &&
|
||||
$this->httpHeaders['HTTP_UA_CPU'] == 'ARM' // Seen this on a HTC.
|
||||
)
|
||||
){
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic overloading method.
|
||||
*
|
||||
* @method boolean is[...]()
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
|
||||
$this->setDetectionType('mobile');
|
||||
|
||||
$key = substr($name, 2);
|
||||
return $this->matchUAAgainstKey($key);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a detection rule that matches the current User-agent.
|
||||
*
|
||||
* @param null $userAgent deprecated
|
||||
* @return boolean
|
||||
*/
|
||||
private function matchDetectionRulesAgainstUA($userAgent = null){
|
||||
|
||||
// Begin general search.
|
||||
foreach($this->getRules() as $_regex){
|
||||
if(empty($_regex)){ continue; }
|
||||
if( $this->match($_regex, $userAgent) ){
|
||||
//var_dump( $_regex );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a certain key in the rules array.
|
||||
* If the key is found the try to match the corresponding
|
||||
* regex agains the User-agent.
|
||||
*
|
||||
* @param string $key
|
||||
* @param null $userAgent deprecated
|
||||
* @return mixed
|
||||
*/
|
||||
private function matchUAAgainstKey($key, $userAgent = null){
|
||||
|
||||
// Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
|
||||
$key = strtolower($key);
|
||||
$_rules = array_change_key_case($this->getRules());
|
||||
|
||||
if(array_key_exists($key, $_rules)){
|
||||
if(empty($_rules[$key])){ return null; }
|
||||
return $this->match($_rules[$key], $userAgent);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the device is mobile.
|
||||
* Returns true if any type of mobile device detected, including special ones
|
||||
* @param null $userAgent deprecated
|
||||
* @param null $httpHeaders deprecated
|
||||
* @return bool
|
||||
*/
|
||||
public function isMobile($userAgent = null, $httpHeaders = null) {
|
||||
|
||||
if($httpHeaders){ $this->setHttpHeaders($httpHeaders); }
|
||||
if($userAgent){ $this->setUserAgent($userAgent); }
|
||||
|
||||
$this->setDetectionType('mobile');
|
||||
|
||||
if ($this->checkHttpHeadersForMobile()) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->matchDetectionRulesAgainstUA();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the device is a tablet.
|
||||
* Return true if any type of tablet device is detected.
|
||||
*
|
||||
* @param null $userAgent deprecated
|
||||
* @param null $httpHeaders deprecated
|
||||
* @return bool
|
||||
*/
|
||||
public function isTablet($userAgent = null, $httpHeaders = null) {
|
||||
|
||||
$this->setDetectionType('mobile');
|
||||
|
||||
foreach($this->tabletDevices as $_regex){
|
||||
if($this->match($_regex, $userAgent)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks for a certain property in the
|
||||
* userAgent.
|
||||
* @todo: The httpHeaders part is not yet used.
|
||||
*
|
||||
* @param $key
|
||||
* @param string $userAgent deprecated
|
||||
* @param string $httpHeaders deprecated
|
||||
* @return bool|int|null
|
||||
*/
|
||||
public function is($key, $userAgent = null, $httpHeaders = null){
|
||||
|
||||
|
||||
// Set the UA and HTTP headers only if needed (eg. batch mode).
|
||||
if($httpHeaders) $this->setHttpHeaders($httpHeaders);
|
||||
if($userAgent) $this->setUserAgent($userAgent);
|
||||
|
||||
$this->setDetectionType('extended');
|
||||
|
||||
return $this->matchUAAgainstKey($key);
|
||||
|
||||
}
|
||||
|
||||
public function getOperatingSystems(){
|
||||
|
||||
return $this->operatingSystems;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Some detection rules are relative (not standard),
|
||||
* because of the diversity of devices, vendors and
|
||||
* their conventions in representing the User-Agent or
|
||||
* the HTTP headers.
|
||||
*
|
||||
* This method will be used to check custom regexes against
|
||||
* the User-Agent string.
|
||||
*
|
||||
* @param $regex
|
||||
* @param string $userAgent
|
||||
* @return bool
|
||||
*
|
||||
* @todo: search in the HTTP headers too.
|
||||
*/
|
||||
function match($regex, $userAgent=null){
|
||||
|
||||
// Escape the special character which is the delimiter.
|
||||
$regex = str_replace('/', '\/', $regex);
|
||||
|
||||
return (bool)preg_match('/'.$regex.'/is', (!empty($userAgent) ? $userAgent : $this->userAgent));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the properties array.
|
||||
* @return array
|
||||
*/
|
||||
function getProperties(){
|
||||
|
||||
return $this->properties;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the version number.
|
||||
*
|
||||
* @param $ver
|
||||
* @return int
|
||||
*/
|
||||
function prepareVersionNo($ver){
|
||||
|
||||
$ver = str_replace(array('_', ' ', '/'), array('.', '.', '.'), $ver);
|
||||
$arrVer = explode('.', $ver, 2);
|
||||
if(isset($arrVer[1])){
|
||||
$arrVer[1] = @str_replace('.', '', $arrVer[1]); // @todo: treat strings versions.
|
||||
}
|
||||
$ver = (float)implode('.', $arrVer);
|
||||
|
||||
return $ver;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the version of the given property in the User-Agent.
|
||||
* Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
|
||||
*
|
||||
* @param string $propertyName
|
||||
* @return mixed $version
|
||||
*/
|
||||
function version($propertyName, $type = 'text'){
|
||||
|
||||
if(empty($propertyName)){ return false; }
|
||||
if( !in_array($type, array('text', 'float')) ){ $type = 'text'; }
|
||||
|
||||
$properties = $this->getProperties();
|
||||
|
||||
// Check if the property exists in the properties array.
|
||||
if( array_key_exists($propertyName, $properties) ){
|
||||
|
||||
// Prepare the pattern to be matched.
|
||||
// Make sure we always deal with an array (string is converted).
|
||||
$properties[$propertyName] = (array)$properties[$propertyName];
|
||||
|
||||
foreach($properties[$propertyName] as $propertyMatchString){
|
||||
|
||||
$propertyPattern = str_replace('[VER]', self::VER, $propertyMatchString);
|
||||
|
||||
// Escape the special character which is the delimiter.
|
||||
$propertyPattern = str_replace('/', '\/', $propertyPattern);
|
||||
|
||||
// Identify and extract the version.
|
||||
preg_match('/'.$propertyPattern.'/is', $this->userAgent, $match);
|
||||
|
||||
if(!empty($match[1])){
|
||||
$version = ( $type == 'float' ? $this->prepareVersionNo($match[1]) : $match[1] );
|
||||
return $version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function mobileGrade(){
|
||||
|
||||
$isMobile = $this->isMobile();
|
||||
|
||||
if(
|
||||
// Apple iOS 3.2-5.1 - Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3), iPad 3 (5.1), original iPhone (3.1), iPhone 3 (3.2), 3GS (4.3), 4 (4.3 / 5.0), and 4S (5.1)
|
||||
$this->version('iPad')>=4.3 ||
|
||||
$this->version('iPhone')>=3.1 ||
|
||||
$this->version('iPod')>=3.1 ||
|
||||
|
||||
// Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
|
||||
// Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
|
||||
// Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
|
||||
// Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
|
||||
( $this->version('Android')>2.1 && $this->is('Webkit') ) ||
|
||||
|
||||
// Windows Phone 7-7.5 - Tested on the HTC Surround (7.0) HTC Trophy (7.5), LG-E900 (7.5), Nokia Lumia 800
|
||||
$this->version('Windows Phone OS')>=7.0 ||
|
||||
|
||||
// Blackberry 7 - Tested on BlackBerry® Torch 9810
|
||||
// Blackberry 6.0 - Tested on the Torch 9800 and Style 9670
|
||||
$this->version('BlackBerry')>=6.0 ||
|
||||
// Blackberry Playbook (1.0-2.0) - Tested on PlayBook
|
||||
$this->match('Playbook.*Tablet') ||
|
||||
|
||||
// Palm WebOS (1.4-2.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0)
|
||||
( $this->version('webOS')>=1.4 && $this->match('Palm|Pre|Pixi') ) ||
|
||||
// Palm WebOS 3.0 - Tested on HP TouchPad
|
||||
$this->match('hp.*TouchPad') ||
|
||||
|
||||
// Firefox Mobile (12 Beta) - Tested on Android 2.3 device
|
||||
( $this->is('Firefox') && $this->version('Firefox')>=12 ) ||
|
||||
|
||||
// Chrome for Android - Tested on Android 4.0, 4.1 device
|
||||
( $this->is('Chrome') && $this->is('AndroidOS') && $this->version('Android')>=4.0 ) ||
|
||||
|
||||
// Skyfire 4.1 - Tested on Android 2.3 device
|
||||
( $this->is('Skyfire') && $this->version('Skyfire')>=4.1 && $this->is('AndroidOS') && $this->version('Android')>=2.3 ) ||
|
||||
|
||||
// Opera Mobile 11.5-12: Tested on Android 2.3
|
||||
( $this->is('Opera') && $this->version('Opera Mobi')>11 && $this->is('AndroidOS') ) ||
|
||||
|
||||
// Meego 1.2 - Tested on Nokia 950 and N9
|
||||
$this->is('MeeGoOS') ||
|
||||
|
||||
// Tizen (pre-release) - Tested on early hardware
|
||||
$this->is('Tizen') ||
|
||||
|
||||
// Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
|
||||
// @todo: more tests here!
|
||||
$this->is('Dolfin') && $this->version('Bada')>=2.0 ||
|
||||
|
||||
// UC Browser - Tested on Android 2.3 device
|
||||
( ($this->is('UC Browser') || $this->is('Dolfin')) && $this->version('Android')>=2.3 ) ||
|
||||
|
||||
// Kindle 3 and Fire - Tested on the built-in WebKit browser for each
|
||||
( $this->match('Kindle Fire') ||
|
||||
$this->is('Kindle') && $this->version('Kindle')>=3.0 ) ||
|
||||
|
||||
// Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
|
||||
$this->is('AndroidOS') && $this->is('NookTablet') ||
|
||||
|
||||
// Chrome Desktop 11-21 - Tested on OS X 10.7 and Windows 7
|
||||
$this->version('Chrome')>=11 && !$isMobile ||
|
||||
|
||||
// Safari Desktop 4-5 - Tested on OS X 10.7 and Windows 7
|
||||
$this->version('Safari')>=5.0 && !$isMobile ||
|
||||
|
||||
// Firefox Desktop 4-13 - Tested on OS X 10.7 and Windows 7
|
||||
$this->version('Firefox')>=4.0 && !$isMobile ||
|
||||
|
||||
// Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
|
||||
$this->version('MSIE')>=7.0 && !$isMobile ||
|
||||
|
||||
// Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
|
||||
// @reference: http://my.opera.com/community/openweb/idopera/
|
||||
$this->version('Opera')>=10 && !$isMobile
|
||||
|
||||
|
||||
){
|
||||
return 'A';
|
||||
}
|
||||
|
||||
if(
|
||||
// Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
|
||||
$this->version('BlackBerry')>=5 && $this->version('BlackBerry')<6 ||
|
||||
|
||||
//Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
|
||||
( $this->version('Opera Mini')>=5.0 && $this->version('Opera Mini')<=6.5 &&
|
||||
($this->version('Android')>=2.3 || $this->is('iOS')) ) ||
|
||||
|
||||
// Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
|
||||
$this->match('NokiaN8|NokiaC7|N97.*Series60|Symbian/3') ||
|
||||
|
||||
// @todo: report this (tested on Nokia N71)
|
||||
$this->version('Opera Mobi')>=11 && $this->is('SymbianOS')
|
||||
|
||||
){
|
||||
return 'B';
|
||||
}
|
||||
|
||||
if(
|
||||
// Blackberry 4.x - Tested on the Curve 8330
|
||||
$this->version('BlackBerry')<5.0 ||
|
||||
// Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
|
||||
$this->match('MSIEMobile|Windows CE.*Mobile') || $this->version('Windows Mobile')<=5.2
|
||||
|
||||
|
||||
){
|
||||
|
||||
return 'C';
|
||||
|
||||
}
|
||||
|
||||
// All older smartphone platforms and featurephones - Any device that doesn't support media queries will receive the basic, C grade experience
|
||||
return 'C';
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
$detect = new Mobile_Detect;
|
||||
@ -5,9 +5,14 @@ function check_acl_access($params, $smarty)
|
||||
{
|
||||
$isAuthenticated = isset($_SESSION['AUTHENTICATED']) ? true : false;
|
||||
$iAclSetting = $params['acl'];
|
||||
$sUrl = '<li class="'.$params['icon'].'"><a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$params['page'].'&action='.$params['action'].'">'.$params['name'].'</a></li>';
|
||||
// $params['icon'] is deprecated, only needed for mpos compatibility
|
||||
if (isset($params['icon'])) {
|
||||
$sUrl = '<li class="'.$params['icon'].'"><a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$params['page'].'&action='.$params['action'].'">'.$params['name'].'</a></li>';
|
||||
} else {
|
||||
$sUrl = '<li><a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$params['page'].'&action='.$params['action'].'">'.$params['name'].'</a></li>';
|
||||
}
|
||||
if (isset($params['fallback']))
|
||||
$sFallbackUrl = '<li class="'.$params['icon'].'"><a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$params['page'].'">'.$params['name'].'</a></li>';
|
||||
$sFallbackUrl = '<li><a href="'.$_SERVER['SCRIPT_NAME'].'?page='.$params['page'].'">'.$params['name'].'</a></li>';
|
||||
switch($iAclSetting) {
|
||||
case '0':
|
||||
if ($isAuthenticated) {
|
||||
|
||||
81
public/include/lib/swiftmailer/classes/Swift.php
Normal file
81
public/include/lib/swiftmailer/classes/Swift.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* General utility class in Swift Mailer, not to be instantiated.
|
||||
*
|
||||
* @package Swift
|
||||
*
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
abstract class Swift
|
||||
{
|
||||
public static $initialized = false;
|
||||
public static $inits = array();
|
||||
|
||||
/** Swift Mailer Version number generated during dist release process */
|
||||
const VERSION = '5.1.0';
|
||||
|
||||
/**
|
||||
* Registers an initializer callable that will be called the first time
|
||||
* a SwiftMailer class is autoloaded.
|
||||
*
|
||||
* This enables you to tweak the default configuration in a lazy way.
|
||||
*
|
||||
* @param mixed $callable A valid PHP callable that will be called when autoloading the first Swift class
|
||||
*/
|
||||
public static function init($callable)
|
||||
{
|
||||
self::$inits[] = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal autoloader for spl_autoload_register().
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
public static function autoload($class)
|
||||
{
|
||||
// Don't interfere with other autoloaders
|
||||
if (0 !== strpos($class, 'Swift_')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = dirname(__FILE__).'/'.str_replace('_', '/', $class).'.php';
|
||||
|
||||
if (!file_exists($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
require $path;
|
||||
|
||||
if (self::$inits && !self::$initialized) {
|
||||
self::$initialized = true;
|
||||
foreach (self::$inits as $init) {
|
||||
call_user_func($init);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure autoloading using Swift Mailer.
|
||||
*
|
||||
* This is designed to play nicely with other autoloaders.
|
||||
*
|
||||
* @param mixed $callable A valid PHP callable that will be called when autoloading the first Swift class
|
||||
*/
|
||||
public static function registerAutoload($callable = null)
|
||||
{
|
||||
if (null !== $callable) {
|
||||
self::$inits[] = $callable;
|
||||
}
|
||||
spl_autoload_register(array('Swift', 'autoload'));
|
||||
}
|
||||
}
|
||||
73
public/include/lib/swiftmailer/classes/Swift/Attachment.php
Normal file
73
public/include/lib/swiftmailer/classes/Swift/Attachment.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Attachment class for attaching files to a {@link Swift_Mime_Message}.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Attachment extends Swift_Mime_Attachment
|
||||
{
|
||||
/**
|
||||
* Create a new Attachment.
|
||||
*
|
||||
* Details may be optionally provided to the constructor.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $data
|
||||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*/
|
||||
public function __construct($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Mime_Attachment::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('mime.attachment')
|
||||
);
|
||||
|
||||
$this->setBody($data);
|
||||
$this->setFilename($filename);
|
||||
if ($contentType) {
|
||||
$this->setContentType($contentType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Attachment.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $data
|
||||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
*/
|
||||
public static function newInstance($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
return new self($data, $filename, $contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Attachment from a filesystem path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $contentType optional
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
*/
|
||||
public static function fromPath($path, $contentType = null)
|
||||
{
|
||||
return self::newInstance()->setFile(
|
||||
new Swift_ByteStream_FileByteStream($path),
|
||||
$contentType
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides the base functionality for an InputStream supporting filters.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage ByteStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
abstract class Swift_ByteStream_AbstractFilterableInputStream implements Swift_InputByteStream, Swift_Filterable
|
||||
{
|
||||
/**
|
||||
* Write sequence.
|
||||
*/
|
||||
protected $_sequence = 0;
|
||||
|
||||
/**
|
||||
* StreamFilters.
|
||||
*/
|
||||
private $_filters = array();
|
||||
|
||||
/**
|
||||
* A buffer for writing.
|
||||
*/
|
||||
private $_writeBuffer = '';
|
||||
|
||||
/**
|
||||
* Bound streams.
|
||||
*
|
||||
* @var Swift_InputByteStream[]
|
||||
*/
|
||||
private $_mirrors = array();
|
||||
|
||||
/**
|
||||
* Commit the given bytes to the storage medium immediately.
|
||||
*
|
||||
* @param string $bytes
|
||||
*/
|
||||
abstract protected function _commit($bytes);
|
||||
|
||||
/**
|
||||
* Flush any buffers/content with immediate effect.
|
||||
*/
|
||||
abstract protected function _flush();
|
||||
|
||||
/**
|
||||
* Add a StreamFilter to this InputByteStream.
|
||||
*
|
||||
* @param Swift_StreamFilter $filter
|
||||
* @param string $key
|
||||
*/
|
||||
public function addFilter(Swift_StreamFilter $filter, $key)
|
||||
{
|
||||
$this->_filters[$key] = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an already present StreamFilter based on its $key.
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
public function removeFilter($key)
|
||||
{
|
||||
unset($this->_filters[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $bytes to the end of the stream.
|
||||
*
|
||||
* @param string $bytes
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function write($bytes)
|
||||
{
|
||||
$this->_writeBuffer .= $bytes;
|
||||
foreach ($this->_filters as $filter) {
|
||||
if ($filter->shouldBuffer($this->_writeBuffer)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->_doWrite($this->_writeBuffer);
|
||||
|
||||
return ++$this->_sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* For any bytes that are currently buffered inside the stream, force them
|
||||
* off the buffer.
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->_doWrite($this->_writeBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach $is to this stream.
|
||||
*
|
||||
* The stream acts as an observer, receiving all data that is written.
|
||||
* All {@link write()} and {@link flushBuffers()} operations will be mirrored.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function bind(Swift_InputByteStream $is)
|
||||
{
|
||||
$this->_mirrors[] = $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an already bound stream.
|
||||
*
|
||||
* If $is is not bound, no errors will be raised.
|
||||
* If the stream currently has any buffered data it will be written to $is
|
||||
* before unbinding occurs.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function unbind(Swift_InputByteStream $is)
|
||||
{
|
||||
foreach ($this->_mirrors as $k => $stream) {
|
||||
if ($is === $stream) {
|
||||
if ($this->_writeBuffer !== '') {
|
||||
$stream->write($this->_writeBuffer);
|
||||
}
|
||||
unset($this->_mirrors[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the contents of the stream (empty it) and set the internal pointer
|
||||
* to the beginning.
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function flushBuffers()
|
||||
{
|
||||
if ($this->_writeBuffer !== '') {
|
||||
$this->_doWrite($this->_writeBuffer);
|
||||
}
|
||||
$this->_flush();
|
||||
|
||||
foreach ($this->_mirrors as $stream) {
|
||||
$stream->flushBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
// -- Private methods
|
||||
|
||||
/** Run $bytes through all filters */
|
||||
private function _filter($bytes)
|
||||
{
|
||||
foreach ($this->_filters as $filter) {
|
||||
$bytes = $filter->filter($bytes);
|
||||
}
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/** Just write the bytes to the stream */
|
||||
private function _doWrite($bytes)
|
||||
{
|
||||
$this->_commit($this->_filter($bytes));
|
||||
|
||||
foreach ($this->_mirrors as $stream) {
|
||||
$stream->write($bytes);
|
||||
}
|
||||
|
||||
$this->_writeBuffer = '';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows reading and writing of bytes to and from an array.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage ByteStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_ByteStream_ArrayByteStream implements Swift_InputByteStream, Swift_OutputByteStream
|
||||
{
|
||||
/**
|
||||
* The internal stack of bytes.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $_array = array();
|
||||
|
||||
/**
|
||||
* The size of the stack
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_arraySize = 0;
|
||||
|
||||
/**
|
||||
* The internal pointer offset.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_offset = 0;
|
||||
|
||||
/**
|
||||
* Bound streams.
|
||||
*
|
||||
* @var Swift_InputByteStream[]
|
||||
*/
|
||||
private $_mirrors = array();
|
||||
|
||||
/**
|
||||
* Create a new ArrayByteStream.
|
||||
*
|
||||
* If $stack is given the stream will be populated with the bytes it contains.
|
||||
*
|
||||
* @param mixed $stack of bytes in string or array form, optional
|
||||
*/
|
||||
public function __construct($stack = null)
|
||||
{
|
||||
if (is_array($stack)) {
|
||||
$this->_array = $stack;
|
||||
$this->_arraySize = count($stack);
|
||||
} elseif (is_string($stack)) {
|
||||
$this->write($stack);
|
||||
} else {
|
||||
$this->_array = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads $length bytes from the stream into a string and moves the pointer
|
||||
* through the stream by $length.
|
||||
*
|
||||
* If less bytes exist than are requested the
|
||||
* remaining bytes are given instead. If no bytes are remaining at all, boolean
|
||||
* false is returned.
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
if ($this->_offset == $this->_arraySize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't use array slice
|
||||
$end = $length + $this->_offset;
|
||||
$end = $this->_arraySize<$end
|
||||
?$this->_arraySize
|
||||
:$end;
|
||||
$ret = '';
|
||||
for (; $this->_offset < $end; ++$this->_offset) {
|
||||
$ret .= $this->_array[$this->_offset];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $bytes to the end of the stream.
|
||||
*
|
||||
* @param string $bytes
|
||||
*/
|
||||
public function write($bytes)
|
||||
{
|
||||
$to_add = str_split($bytes);
|
||||
foreach ($to_add as $value) {
|
||||
$this->_array[] = $value;
|
||||
}
|
||||
$this->_arraySize = count($this->_array);
|
||||
|
||||
foreach ($this->_mirrors as $stream) {
|
||||
$stream->write($bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach $is to this stream.
|
||||
*
|
||||
* The stream acts as an observer, receiving all data that is written.
|
||||
* All {@link write()} and {@link flushBuffers()} operations will be mirrored.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function bind(Swift_InputByteStream $is)
|
||||
{
|
||||
$this->_mirrors[] = $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an already bound stream.
|
||||
*
|
||||
* If $is is not bound, no errors will be raised.
|
||||
* If the stream currently has any buffered data it will be written to $is
|
||||
* before unbinding occurs.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function unbind(Swift_InputByteStream $is)
|
||||
{
|
||||
foreach ($this->_mirrors as $k => $stream) {
|
||||
if ($is === $stream) {
|
||||
unset($this->_mirrors[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal read pointer to $byteOffset in the stream.
|
||||
*
|
||||
* @param integer $byteOffset
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function setReadPointer($byteOffset)
|
||||
{
|
||||
if ($byteOffset > $this->_arraySize) {
|
||||
$byteOffset = $this->_arraySize;
|
||||
} elseif ($byteOffset < 0) {
|
||||
$byteOffset = 0;
|
||||
}
|
||||
|
||||
$this->_offset = $byteOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the contents of the stream (empty it) and set the internal pointer
|
||||
* to the beginning.
|
||||
*/
|
||||
public function flushBuffers()
|
||||
{
|
||||
$this->_offset = 0;
|
||||
$this->_array = array();
|
||||
$this->_arraySize = 0;
|
||||
|
||||
foreach ($this->_mirrors as $stream) {
|
||||
$stream->flushBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows reading and writing of bytes to and from a file.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage ByteStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterableInputStream implements Swift_FileStream
|
||||
{
|
||||
/** The internal pointer offset */
|
||||
private $_offset = 0;
|
||||
|
||||
/** The path to the file */
|
||||
private $_path;
|
||||
|
||||
/** The mode this file is opened in for writing */
|
||||
private $_mode;
|
||||
|
||||
/** A lazy-loaded resource handle for reading the file */
|
||||
private $_reader;
|
||||
|
||||
/** A lazy-loaded resource handle for writing the file */
|
||||
private $_writer;
|
||||
|
||||
/** If magic_quotes_runtime is on, this will be true */
|
||||
private $_quotes = false;
|
||||
|
||||
/** If stream is seekable true/false, or null if not known */
|
||||
private $_seekable = null;
|
||||
|
||||
/**
|
||||
* Create a new FileByteStream for $path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param boolean $writable if true
|
||||
*/
|
||||
public function __construct($path, $writable = false)
|
||||
{
|
||||
if (empty($path)) {
|
||||
throw new Swift_IoException('The path cannot be empty');
|
||||
}
|
||||
$this->_path = $path;
|
||||
$this->_mode = $writable ? 'w+b' : 'rb';
|
||||
|
||||
if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) {
|
||||
$this->_quotes = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the complete path to the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads $length bytes from the stream into a string and moves the pointer
|
||||
* through the stream by $length.
|
||||
*
|
||||
* If less bytes exist than are requested the
|
||||
* remaining bytes are given instead. If no bytes are remaining at all, boolean
|
||||
* false is returned.
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
$fp = $this->_getReadHandle();
|
||||
if (!feof($fp)) {
|
||||
if ($this->_quotes) {
|
||||
ini_set('magic_quotes_runtime', 0);
|
||||
}
|
||||
$bytes = fread($fp, $length);
|
||||
if ($this->_quotes) {
|
||||
ini_set('magic_quotes_runtime', 1);
|
||||
}
|
||||
$this->_offset = ftell($fp);
|
||||
|
||||
return $bytes;
|
||||
} else {
|
||||
$this->_resetReadHandle();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal read pointer to $byteOffset in the stream.
|
||||
*
|
||||
* @param integer $byteOffset
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function setReadPointer($byteOffset)
|
||||
{
|
||||
if (isset($this->_reader)) {
|
||||
$this->_seekReadStreamToPosition($byteOffset);
|
||||
}
|
||||
$this->_offset = $byteOffset;
|
||||
}
|
||||
|
||||
// -- Private methods
|
||||
|
||||
/** Just write the bytes to the file */
|
||||
protected function _commit($bytes)
|
||||
{
|
||||
fwrite($this->_getWriteHandle(), $bytes);
|
||||
$this->_resetReadHandle();
|
||||
}
|
||||
|
||||
/** Not used */
|
||||
protected function _flush()
|
||||
{
|
||||
}
|
||||
|
||||
/** Get the resource for reading */
|
||||
private function _getReadHandle()
|
||||
{
|
||||
if (!isset($this->_reader)) {
|
||||
if (!$this->_reader = fopen($this->_path, 'rb')) {
|
||||
throw new Swift_IoException(
|
||||
'Unable to open file for reading [' . $this->_path . ']'
|
||||
);
|
||||
}
|
||||
if ($this->_offset <> 0) {
|
||||
$this->_getReadStreamSeekableStatus();
|
||||
$this->_seekReadStreamToPosition($this->_offset);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_reader;
|
||||
}
|
||||
|
||||
/** Get the resource for writing */
|
||||
private function _getWriteHandle()
|
||||
{
|
||||
if (!isset($this->_writer)) {
|
||||
if (!$this->_writer = fopen($this->_path, $this->_mode)) {
|
||||
throw new Swift_IoException(
|
||||
'Unable to open file for writing [' . $this->_path . ']'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_writer;
|
||||
}
|
||||
|
||||
/** Force a reload of the resource for reading */
|
||||
private function _resetReadHandle()
|
||||
{
|
||||
if (isset($this->_reader)) {
|
||||
fclose($this->_reader);
|
||||
$this->_reader = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Check if ReadOnly Stream is seekable */
|
||||
private function _getReadStreamSeekableStatus()
|
||||
{
|
||||
$metas = stream_get_meta_data($this->_reader);
|
||||
$this->_seekable = $metas['seekable'];
|
||||
}
|
||||
|
||||
/** Streams in a readOnly stream ensuring copy if needed */
|
||||
private function _seekReadStreamToPosition($offset)
|
||||
{
|
||||
if ($this->_seekable===null) {
|
||||
$this->_getReadStreamSeekableStatus();
|
||||
}
|
||||
if ($this->_seekable === false) {
|
||||
$currentPos = ftell($this->_reader);
|
||||
if ($currentPos<$offset) {
|
||||
$toDiscard = $offset-$currentPos;
|
||||
fread($this->_reader, $toDiscard);
|
||||
|
||||
return;
|
||||
}
|
||||
$this->_copyReadStream();
|
||||
}
|
||||
fseek($this->_reader, $offset, SEEK_SET);
|
||||
}
|
||||
|
||||
/** Copy a readOnly Stream to ensure seekability */
|
||||
private function _copyReadStream()
|
||||
{
|
||||
if ($tmpFile = fopen('php://temp/maxmemory:4096', 'w+b')) {
|
||||
/* We have opened a php:// Stream Should work without problem */
|
||||
} elseif (function_exists('sys_get_temp_dir') && is_writable(sys_get_temp_dir()) && ($tmpFile = tmpfile())) {
|
||||
/* We have opened a tmpfile */
|
||||
} else {
|
||||
throw new Swift_IoException('Unable to copy the file to make it seekable, sys_temp_dir is not writable, php://memory not available');
|
||||
}
|
||||
$currentPos = ftell($this->_reader);
|
||||
fclose($this->_reader);
|
||||
$source = fopen($this->_path, 'rb');
|
||||
if (!$source) {
|
||||
throw new Swift_IoException('Unable to open file for copying [' . $this->_path . ']');
|
||||
}
|
||||
fseek($tmpFile, 0, SEEK_SET);
|
||||
while (!feof($source)) {
|
||||
fwrite($tmpFile, fread($source, 4096));
|
||||
}
|
||||
fseek($tmpFile, $currentPos, SEEK_SET);
|
||||
fclose($source);
|
||||
$this->_reader = $tmpFile;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @package Swift
|
||||
* @subpackage ByteStream
|
||||
* @author Romain-Geissler
|
||||
*/
|
||||
class Swift_ByteStream_TemporaryFileByteStream extends Swift_ByteStream_FileByteStream
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$filePath = tempnam(sys_get_temp_dir(), 'FileByteStream');
|
||||
|
||||
if ($filePath === false) {
|
||||
throw new Swift_IoException('Failed to retrieve temporary file name.');
|
||||
}
|
||||
|
||||
parent::__construct($filePath, true);
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
if (($content = file_get_contents($this->getPath())) === false) {
|
||||
throw new Swift_IoException('Failed to get temporary file content.');
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (file_exists($this->getPath())) {
|
||||
@unlink($this->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Analyzes characters for a specific character set.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
* @author Xavier De Cock <xdecock@gmail.com>
|
||||
*/
|
||||
interface Swift_CharacterReader
|
||||
{
|
||||
const MAP_TYPE_INVALID = 0x01;
|
||||
const MAP_TYPE_FIXED_LEN = 0x02;
|
||||
const MAP_TYPE_POSITIONS = 0x03;
|
||||
|
||||
/**
|
||||
* Returns the complete character map
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $startOffset
|
||||
* @param array $currentMap
|
||||
* @param mixed $ignoredChars
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars);
|
||||
|
||||
/**
|
||||
* Returns the mapType, see constants.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getMapType();
|
||||
|
||||
/**
|
||||
* Returns an integer which specifies how many more bytes to read.
|
||||
*
|
||||
* A positive integer indicates the number of more bytes to fetch before invoking
|
||||
* this method again.
|
||||
*
|
||||
* A value of zero means this is already a valid character.
|
||||
* A value of -1 means this cannot possibly be a valid character.
|
||||
*
|
||||
* @param integer[] $bytes
|
||||
* @param integer $size
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function validateByteSequence($bytes, $size);
|
||||
|
||||
/**
|
||||
* Returns the number of bytes which should be read to start each character.
|
||||
*
|
||||
* For fixed width character sets this should be the number of octets-per-character.
|
||||
* For multibyte character sets this will probably be 1.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getInitialByteSize();
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides fixed-width byte sizes for reading fixed-width character sets.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
* @author Xavier De Cock <xdecock@gmail.com>
|
||||
*/
|
||||
class Swift_CharacterReader_GenericFixedWidthReader implements Swift_CharacterReader
|
||||
{
|
||||
/**
|
||||
* The number of bytes in a single character.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_width;
|
||||
|
||||
/**
|
||||
* Creates a new GenericFixedWidthReader using $width bytes per character.
|
||||
*
|
||||
* @param integer $width
|
||||
*/
|
||||
public function __construct($width)
|
||||
{
|
||||
$this->_width = $width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the complete character map.
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $startOffset
|
||||
* @param array $currentMap
|
||||
* @param mixed $ignoredChars
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars)
|
||||
{
|
||||
$strlen = strlen($string);
|
||||
// % and / are CPU intensive, so, maybe find a better way
|
||||
$ignored = $strlen % $this->_width;
|
||||
$ignoredChars = substr($string, - $ignored);
|
||||
$currentMap = $this->_width;
|
||||
|
||||
return ($strlen - $ignored) / $this->_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapType.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getMapType()
|
||||
{
|
||||
return self::MAP_TYPE_FIXED_LEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an integer which specifies how many more bytes to read.
|
||||
*
|
||||
* A positive integer indicates the number of more bytes to fetch before invoking
|
||||
* this method again.
|
||||
*
|
||||
* A value of zero means this is already a valid character.
|
||||
* A value of -1 means this cannot possibly be a valid character.
|
||||
*
|
||||
* @param string $bytes
|
||||
* @param integer $size
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function validateByteSequence($bytes, $size)
|
||||
{
|
||||
$needed = $this->_width - $size;
|
||||
|
||||
return ($needed > -1) ? $needed : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes which should be read to start each character.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getInitialByteSize()
|
||||
{
|
||||
return $this->_width;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Analyzes US-ASCII characters.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_CharacterReader_UsAsciiReader implements Swift_CharacterReader
|
||||
{
|
||||
/**
|
||||
* Returns the complete character map.
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $startOffset
|
||||
* @param array $currentMap
|
||||
* @param string $ignoredChars
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars)
|
||||
{
|
||||
$strlen=strlen($string);
|
||||
$ignoredChars='';
|
||||
for ($i = 0; $i < $strlen; ++$i) {
|
||||
if ($string[$i]>"\x07F") { // Invalid char
|
||||
$currentMap[$i+$startOffset]=$string[$i];
|
||||
}
|
||||
}
|
||||
|
||||
return $strlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mapType
|
||||
*
|
||||
* @return integer mapType
|
||||
*/
|
||||
public function getMapType()
|
||||
{
|
||||
return self::MAP_TYPE_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an integer which specifies how many more bytes to read.
|
||||
*
|
||||
* A positive integer indicates the number of more bytes to fetch before invoking
|
||||
* this method again.
|
||||
* A value of zero means this is already a valid character.
|
||||
* A value of -1 means this cannot possibly be a valid character.
|
||||
*
|
||||
* @param string $bytes
|
||||
* @param integer $size
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function validateByteSequence($bytes, $size)
|
||||
{
|
||||
$byte = reset($bytes);
|
||||
if (1 == count($bytes) && $byte >= 0x00 && $byte <= 0x7F) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes which should be read to start each character.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getInitialByteSize()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Analyzes UTF-8 characters.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
* @author Xavier De Cock <xdecock@gmail.com>
|
||||
*/
|
||||
class Swift_CharacterReader_Utf8Reader implements Swift_CharacterReader
|
||||
{
|
||||
/** Pre-computed for optimization */
|
||||
private static $length_map=array(
|
||||
// N=0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x0N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x2N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x4N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x6N
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7N
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x8N
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9N
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xAN
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBN
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xCN
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDN
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEN
|
||||
4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0 // 0xFN
|
||||
);
|
||||
|
||||
private static $s_length_map=array(
|
||||
"\x00"=>1, "\x01"=>1, "\x02"=>1, "\x03"=>1, "\x04"=>1, "\x05"=>1, "\x06"=>1, "\x07"=>1,
|
||||
"\x08"=>1, "\x09"=>1, "\x0a"=>1, "\x0b"=>1, "\x0c"=>1, "\x0d"=>1, "\x0e"=>1, "\x0f"=>1,
|
||||
"\x10"=>1, "\x11"=>1, "\x12"=>1, "\x13"=>1, "\x14"=>1, "\x15"=>1, "\x16"=>1, "\x17"=>1,
|
||||
"\x18"=>1, "\x19"=>1, "\x1a"=>1, "\x1b"=>1, "\x1c"=>1, "\x1d"=>1, "\x1e"=>1, "\x1f"=>1,
|
||||
"\x20"=>1, "\x21"=>1, "\x22"=>1, "\x23"=>1, "\x24"=>1, "\x25"=>1, "\x26"=>1, "\x27"=>1,
|
||||
"\x28"=>1, "\x29"=>1, "\x2a"=>1, "\x2b"=>1, "\x2c"=>1, "\x2d"=>1, "\x2e"=>1, "\x2f"=>1,
|
||||
"\x30"=>1, "\x31"=>1, "\x32"=>1, "\x33"=>1, "\x34"=>1, "\x35"=>1, "\x36"=>1, "\x37"=>1,
|
||||
"\x38"=>1, "\x39"=>1, "\x3a"=>1, "\x3b"=>1, "\x3c"=>1, "\x3d"=>1, "\x3e"=>1, "\x3f"=>1,
|
||||
"\x40"=>1, "\x41"=>1, "\x42"=>1, "\x43"=>1, "\x44"=>1, "\x45"=>1, "\x46"=>1, "\x47"=>1,
|
||||
"\x48"=>1, "\x49"=>1, "\x4a"=>1, "\x4b"=>1, "\x4c"=>1, "\x4d"=>1, "\x4e"=>1, "\x4f"=>1,
|
||||
"\x50"=>1, "\x51"=>1, "\x52"=>1, "\x53"=>1, "\x54"=>1, "\x55"=>1, "\x56"=>1, "\x57"=>1,
|
||||
"\x58"=>1, "\x59"=>1, "\x5a"=>1, "\x5b"=>1, "\x5c"=>1, "\x5d"=>1, "\x5e"=>1, "\x5f"=>1,
|
||||
"\x60"=>1, "\x61"=>1, "\x62"=>1, "\x63"=>1, "\x64"=>1, "\x65"=>1, "\x66"=>1, "\x67"=>1,
|
||||
"\x68"=>1, "\x69"=>1, "\x6a"=>1, "\x6b"=>1, "\x6c"=>1, "\x6d"=>1, "\x6e"=>1, "\x6f"=>1,
|
||||
"\x70"=>1, "\x71"=>1, "\x72"=>1, "\x73"=>1, "\x74"=>1, "\x75"=>1, "\x76"=>1, "\x77"=>1,
|
||||
"\x78"=>1, "\x79"=>1, "\x7a"=>1, "\x7b"=>1, "\x7c"=>1, "\x7d"=>1, "\x7e"=>1, "\x7f"=>1,
|
||||
"\x80"=>0, "\x81"=>0, "\x82"=>0, "\x83"=>0, "\x84"=>0, "\x85"=>0, "\x86"=>0, "\x87"=>0,
|
||||
"\x88"=>0, "\x89"=>0, "\x8a"=>0, "\x8b"=>0, "\x8c"=>0, "\x8d"=>0, "\x8e"=>0, "\x8f"=>0,
|
||||
"\x90"=>0, "\x91"=>0, "\x92"=>0, "\x93"=>0, "\x94"=>0, "\x95"=>0, "\x96"=>0, "\x97"=>0,
|
||||
"\x98"=>0, "\x99"=>0, "\x9a"=>0, "\x9b"=>0, "\x9c"=>0, "\x9d"=>0, "\x9e"=>0, "\x9f"=>0,
|
||||
"\xa0"=>0, "\xa1"=>0, "\xa2"=>0, "\xa3"=>0, "\xa4"=>0, "\xa5"=>0, "\xa6"=>0, "\xa7"=>0,
|
||||
"\xa8"=>0, "\xa9"=>0, "\xaa"=>0, "\xab"=>0, "\xac"=>0, "\xad"=>0, "\xae"=>0, "\xaf"=>0,
|
||||
"\xb0"=>0, "\xb1"=>0, "\xb2"=>0, "\xb3"=>0, "\xb4"=>0, "\xb5"=>0, "\xb6"=>0, "\xb7"=>0,
|
||||
"\xb8"=>0, "\xb9"=>0, "\xba"=>0, "\xbb"=>0, "\xbc"=>0, "\xbd"=>0, "\xbe"=>0, "\xbf"=>0,
|
||||
"\xc0"=>2, "\xc1"=>2, "\xc2"=>2, "\xc3"=>2, "\xc4"=>2, "\xc5"=>2, "\xc6"=>2, "\xc7"=>2,
|
||||
"\xc8"=>2, "\xc9"=>2, "\xca"=>2, "\xcb"=>2, "\xcc"=>2, "\xcd"=>2, "\xce"=>2, "\xcf"=>2,
|
||||
"\xd0"=>2, "\xd1"=>2, "\xd2"=>2, "\xd3"=>2, "\xd4"=>2, "\xd5"=>2, "\xd6"=>2, "\xd7"=>2,
|
||||
"\xd8"=>2, "\xd9"=>2, "\xda"=>2, "\xdb"=>2, "\xdc"=>2, "\xdd"=>2, "\xde"=>2, "\xdf"=>2,
|
||||
"\xe0"=>3, "\xe1"=>3, "\xe2"=>3, "\xe3"=>3, "\xe4"=>3, "\xe5"=>3, "\xe6"=>3, "\xe7"=>3,
|
||||
"\xe8"=>3, "\xe9"=>3, "\xea"=>3, "\xeb"=>3, "\xec"=>3, "\xed"=>3, "\xee"=>3, "\xef"=>3,
|
||||
"\xf0"=>4, "\xf1"=>4, "\xf2"=>4, "\xf3"=>4, "\xf4"=>4, "\xf5"=>4, "\xf6"=>4, "\xf7"=>4,
|
||||
"\xf8"=>5, "\xf9"=>5, "\xfa"=>5, "\xfb"=>5, "\xfc"=>6, "\xfd"=>6, "\xfe"=>0, "\xff"=>0,
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the complete character map.
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $startOffset
|
||||
* @param array $currentMap
|
||||
* @param mixed $ignoredChars
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCharPositions($string, $startOffset, &$currentMap, &$ignoredChars)
|
||||
{
|
||||
if (!isset($currentMap['i']) || ! isset($currentMap['p'])) {
|
||||
$currentMap['p'] = $currentMap['i'] = array();
|
||||
}
|
||||
|
||||
$strlen=strlen($string);
|
||||
$charPos=count($currentMap['p']);
|
||||
$foundChars=0;
|
||||
$invalid=false;
|
||||
for ($i = 0; $i < $strlen; ++$i) {
|
||||
$char = $string[$i];
|
||||
$size = self::$s_length_map[$char];
|
||||
if ($size == 0) {
|
||||
/* char is invalid, we must wait for a resync */
|
||||
$invalid = true;
|
||||
continue;
|
||||
} else {
|
||||
if ($invalid == true) {
|
||||
/* We mark the chars as invalid and start a new char */
|
||||
$currentMap['p'][$charPos + $foundChars] = $startOffset + $i;
|
||||
$currentMap['i'][$charPos + $foundChars] = true;
|
||||
++$foundChars;
|
||||
$invalid = false;
|
||||
}
|
||||
if (($i + $size) > $strlen) {
|
||||
$ignoredChars = substr($string, $i);
|
||||
break;
|
||||
}
|
||||
for ($j = 1; $j < $size; ++$j) {
|
||||
$char = $string[$i + $j];
|
||||
if ($char > "\x7F" && $char < "\xC0") {
|
||||
// Valid - continue parsing
|
||||
} else {
|
||||
/* char is invalid, we must wait for a resync */
|
||||
$invalid = true;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
/* Ok we got a complete char here */
|
||||
$currentMap['p'][$charPos + $foundChars] = $startOffset + $i + $size;
|
||||
$i += $j - 1;
|
||||
++$foundChars;
|
||||
}
|
||||
}
|
||||
|
||||
return $foundChars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mapType.
|
||||
*
|
||||
* @return integer mapType
|
||||
*/
|
||||
public function getMapType()
|
||||
{
|
||||
return self::MAP_TYPE_POSITIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an integer which specifies how many more bytes to read.
|
||||
*
|
||||
* A positive integer indicates the number of more bytes to fetch before invoking
|
||||
* this method again.
|
||||
* A value of zero means this is already a valid character.
|
||||
* A value of -1 means this cannot possibly be a valid character.
|
||||
*
|
||||
* @param string $bytes
|
||||
* @param integer $size
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function validateByteSequence($bytes, $size)
|
||||
{
|
||||
if ($size<1) {
|
||||
return -1;
|
||||
}
|
||||
$needed = self::$length_map[$bytes[0]] - $size;
|
||||
|
||||
return ($needed > -1)
|
||||
? $needed
|
||||
: -1
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes which should be read to start each character.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getInitialByteSize()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A factory for creating CharacterReaders.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_CharacterReaderFactory
|
||||
{
|
||||
/**
|
||||
* Returns a CharacterReader suitable for the charset applied.
|
||||
*
|
||||
* @param string $charset
|
||||
*
|
||||
* @return Swift_CharacterReader
|
||||
*/
|
||||
public function getReaderFor($charset);
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standard factory for creating CharacterReaders.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_CharacterReaderFactory_SimpleCharacterReaderFactory implements Swift_CharacterReaderFactory
|
||||
{
|
||||
/**
|
||||
* A map of charset patterns to their implementation classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_map = array();
|
||||
|
||||
/**
|
||||
* Factories which have already been loaded.
|
||||
*
|
||||
* @var Swift_CharacterReaderFactory[]
|
||||
*/
|
||||
private static $_loaded = array();
|
||||
|
||||
/**
|
||||
* Creates a new CharacterReaderFactory.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->init();
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
$this->init();
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (count(self::$_map) > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$prefix = 'Swift_CharacterReader_';
|
||||
|
||||
$singleByte = array(
|
||||
'class' => $prefix . 'GenericFixedWidthReader',
|
||||
'constructor' => array(1)
|
||||
);
|
||||
|
||||
$doubleByte = array(
|
||||
'class' => $prefix . 'GenericFixedWidthReader',
|
||||
'constructor' => array(2)
|
||||
);
|
||||
|
||||
$fourBytes = array(
|
||||
'class' => $prefix . 'GenericFixedWidthReader',
|
||||
'constructor' => array(4)
|
||||
);
|
||||
|
||||
// Utf-8
|
||||
self::$_map['utf-?8'] = array(
|
||||
'class' => $prefix . 'Utf8Reader',
|
||||
'constructor' => array()
|
||||
);
|
||||
|
||||
//7-8 bit charsets
|
||||
self::$_map['(us-)?ascii'] = $singleByte;
|
||||
self::$_map['(iso|iec)-?8859-?[0-9]+'] = $singleByte;
|
||||
self::$_map['windows-?125[0-9]'] = $singleByte;
|
||||
self::$_map['cp-?[0-9]+'] = $singleByte;
|
||||
self::$_map['ansi'] = $singleByte;
|
||||
self::$_map['macintosh'] = $singleByte;
|
||||
self::$_map['koi-?7'] = $singleByte;
|
||||
self::$_map['koi-?8-?.+'] = $singleByte;
|
||||
self::$_map['mik'] = $singleByte;
|
||||
self::$_map['(cork|t1)'] = $singleByte;
|
||||
self::$_map['v?iscii'] = $singleByte;
|
||||
|
||||
//16 bits
|
||||
self::$_map['(ucs-?2|utf-?16)'] = $doubleByte;
|
||||
|
||||
//32 bits
|
||||
self::$_map['(ucs-?4|utf-?32)'] = $fourBytes;
|
||||
|
||||
// Fallback
|
||||
self::$_map['.*'] = $singleByte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CharacterReader suitable for the charset applied.
|
||||
*
|
||||
* @param string $charset
|
||||
*
|
||||
* @return Swift_CharacterReader
|
||||
*/
|
||||
public function getReaderFor($charset)
|
||||
{
|
||||
$charset = trim(strtolower($charset));
|
||||
foreach (self::$_map as $pattern => $spec) {
|
||||
$re = '/^' . $pattern . '$/D';
|
||||
if (preg_match($re, $charset)) {
|
||||
if (!array_key_exists($pattern, self::$_loaded)) {
|
||||
$reflector = new ReflectionClass($spec['class']);
|
||||
if ($reflector->getConstructor()) {
|
||||
$reader = $reflector->newInstanceArgs($spec['constructor']);
|
||||
} else {
|
||||
$reader = $reflector->newInstance();
|
||||
}
|
||||
self::$_loaded[$pattern] = $reader;
|
||||
}
|
||||
|
||||
return self::$_loaded[$pattern];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract means of reading and writing data in terms of characters as opposed
|
||||
* to bytes.
|
||||
*
|
||||
* Classes implementing this interface may use a subsystem which requires less
|
||||
* memory than working with large strings of data.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage CharacterStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_CharacterStream
|
||||
{
|
||||
/**
|
||||
* Set the character set used in this CharacterStream.
|
||||
*
|
||||
* @param string $charset
|
||||
*/
|
||||
public function setCharacterSet($charset);
|
||||
|
||||
/**
|
||||
* Set the CharacterReaderFactory for multi charset support.
|
||||
*
|
||||
* @param Swift_CharacterReaderFactory $factory
|
||||
*/
|
||||
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory);
|
||||
|
||||
/**
|
||||
* Overwrite this character stream using the byte sequence in the byte stream.
|
||||
*
|
||||
* @param Swift_OutputByteStream $os output stream to read from
|
||||
*/
|
||||
public function importByteStream(Swift_OutputByteStream $os);
|
||||
|
||||
/**
|
||||
* Import a string a bytes into this CharacterStream, overwriting any existing
|
||||
* data in the stream.
|
||||
*
|
||||
* @param string $string
|
||||
*/
|
||||
public function importString($string);
|
||||
|
||||
/**
|
||||
* Read $length characters from the stream and move the internal pointer
|
||||
* $length further into the stream.
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read($length);
|
||||
|
||||
/**
|
||||
* Read $length characters from the stream and return a 1-dimensional array
|
||||
* containing there octet values.
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function readBytes($length);
|
||||
|
||||
/**
|
||||
* Write $chars to the end of the stream.
|
||||
*
|
||||
* @param string $chars
|
||||
*/
|
||||
public function write($chars);
|
||||
|
||||
/**
|
||||
* Move the internal pointer to $charOffset in the stream.
|
||||
*
|
||||
* @param integer $charOffset
|
||||
*/
|
||||
public function setPointer($charOffset);
|
||||
|
||||
/**
|
||||
* Empty the stream and reset the internal pointer.
|
||||
*/
|
||||
public function flushContents();
|
||||
}
|
||||
@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A CharacterStream implementation which stores characters in an internal array.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage CharacterStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStream
|
||||
{
|
||||
/** A map of byte values and their respective characters */
|
||||
private static $_charMap;
|
||||
|
||||
/** A map of characters and their derivative byte values */
|
||||
private static $_byteMap;
|
||||
|
||||
/** The char reader (lazy-loaded) for the current charset */
|
||||
private $_charReader;
|
||||
|
||||
/** A factory for creating CharacterReader instances */
|
||||
private $_charReaderFactory;
|
||||
|
||||
/** The character set this stream is using */
|
||||
private $_charset;
|
||||
|
||||
/** Array of characters */
|
||||
private $_array = array();
|
||||
|
||||
/** Size of the array of character */
|
||||
private $_array_size = array();
|
||||
|
||||
/** The current character offset in the stream */
|
||||
private $_offset = 0;
|
||||
|
||||
/**
|
||||
* Create a new CharacterStream with the given $chars, if set.
|
||||
*
|
||||
* @param Swift_CharacterReaderFactory $factory for loading validators
|
||||
* @param string $charset used in the stream
|
||||
*/
|
||||
public function __construct(Swift_CharacterReaderFactory $factory, $charset)
|
||||
{
|
||||
self::_initializeMaps();
|
||||
$this->setCharacterReaderFactory($factory);
|
||||
$this->setCharacterSet($charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the character set used in this CharacterStream.
|
||||
*
|
||||
* @param string $charset
|
||||
*/
|
||||
public function setCharacterSet($charset)
|
||||
{
|
||||
$this->_charset = $charset;
|
||||
$this->_charReader = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CharacterReaderFactory for multi charset support.
|
||||
*
|
||||
* @param Swift_CharacterReaderFactory $factory
|
||||
*/
|
||||
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
|
||||
{
|
||||
$this->_charReaderFactory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite this character stream using the byte sequence in the byte stream.
|
||||
*
|
||||
* @param Swift_OutputByteStream $os output stream to read from
|
||||
*/
|
||||
public function importByteStream(Swift_OutputByteStream $os)
|
||||
{
|
||||
if (!isset($this->_charReader)) {
|
||||
$this->_charReader = $this->_charReaderFactory
|
||||
->getReaderFor($this->_charset);
|
||||
}
|
||||
|
||||
$startLength = $this->_charReader->getInitialByteSize();
|
||||
while (false !== $bytes = $os->read($startLength)) {
|
||||
$c = array();
|
||||
for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
|
||||
$c[] = self::$_byteMap[$bytes[$i]];
|
||||
}
|
||||
$size = count($c);
|
||||
$need = $this->_charReader
|
||||
->validateByteSequence($c, $size);
|
||||
if ($need > 0 &&
|
||||
false !== $bytes = $os->read($need))
|
||||
{
|
||||
for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
|
||||
$c[] = self::$_byteMap[$bytes[$i]];
|
||||
}
|
||||
}
|
||||
$this->_array[] = $c;
|
||||
++$this->_array_size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a string a bytes into this CharacterStream, overwriting any existing
|
||||
* data in the stream.
|
||||
*
|
||||
* @param string $string
|
||||
*/
|
||||
public function importString($string)
|
||||
{
|
||||
$this->flushContents();
|
||||
$this->write($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read $length characters from the stream and move the internal pointer
|
||||
* $length further into the stream.
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
if ($this->_offset == $this->_array_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't use array slice
|
||||
$arrays = array();
|
||||
$end = $length + $this->_offset;
|
||||
for ($i = $this->_offset; $i < $end; ++$i) {
|
||||
if (!isset($this->_array[$i])) {
|
||||
break;
|
||||
}
|
||||
$arrays[] = $this->_array[$i];
|
||||
}
|
||||
$this->_offset += $i - $this->_offset; // Limit function calls
|
||||
$chars = false;
|
||||
foreach ($arrays as $array) {
|
||||
$chars .= implode('', array_map('chr', $array));
|
||||
}
|
||||
|
||||
return $chars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read $length characters from the stream and return a 1-dimensional array
|
||||
* containing there octet values.
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return integer[]
|
||||
*/
|
||||
public function readBytes($length)
|
||||
{
|
||||
if ($this->_offset == $this->_array_size) {
|
||||
return false;
|
||||
}
|
||||
$arrays = array();
|
||||
$end = $length + $this->_offset;
|
||||
for ($i = $this->_offset; $i < $end; ++$i) {
|
||||
if (!isset($this->_array[$i])) {
|
||||
break;
|
||||
}
|
||||
$arrays[] = $this->_array[$i];
|
||||
}
|
||||
$this->_offset += ($i - $this->_offset); // Limit function calls
|
||||
|
||||
return call_user_func_array('array_merge', $arrays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write $chars to the end of the stream.
|
||||
*
|
||||
* @param string $chars
|
||||
*/
|
||||
public function write($chars)
|
||||
{
|
||||
if (!isset($this->_charReader)) {
|
||||
$this->_charReader = $this->_charReaderFactory->getReaderFor(
|
||||
$this->_charset);
|
||||
}
|
||||
|
||||
$startLength = $this->_charReader->getInitialByteSize();
|
||||
|
||||
$fp = fopen('php://memory', 'w+b');
|
||||
fwrite($fp, $chars);
|
||||
unset($chars);
|
||||
fseek($fp, 0, SEEK_SET);
|
||||
|
||||
$buffer = array(0);
|
||||
$buf_pos = 1;
|
||||
$buf_len = 1;
|
||||
$has_datas = true;
|
||||
do {
|
||||
$bytes = array();
|
||||
// Buffer Filing
|
||||
if ($buf_len - $buf_pos < $startLength) {
|
||||
$buf = array_splice($buffer, $buf_pos);
|
||||
$new = $this->_reloadBuffer($fp, 100);
|
||||
if ($new) {
|
||||
$buffer = array_merge($buf, $new);
|
||||
$buf_len = count($buffer);
|
||||
$buf_pos = 0;
|
||||
} else {
|
||||
$has_datas = false;
|
||||
}
|
||||
}
|
||||
if ($buf_len - $buf_pos > 0) {
|
||||
$size = 0;
|
||||
for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) {
|
||||
++$size;
|
||||
$bytes[] = $buffer[$buf_pos++];
|
||||
}
|
||||
$need = $this->_charReader->validateByteSequence(
|
||||
$bytes, $size);
|
||||
if ($need > 0) {
|
||||
if ($buf_len - $buf_pos < $need) {
|
||||
$new = $this->_reloadBuffer($fp, $need);
|
||||
|
||||
if ($new) {
|
||||
$buffer = array_merge($buffer, $new);
|
||||
$buf_len = count($buffer);
|
||||
}
|
||||
}
|
||||
for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) {
|
||||
$bytes[] = $buffer[$buf_pos++];
|
||||
}
|
||||
}
|
||||
$this->_array[] = $bytes;
|
||||
++$this->_array_size;
|
||||
}
|
||||
} while ($has_datas);
|
||||
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the internal pointer to $charOffset in the stream.
|
||||
*
|
||||
* @param integer $charOffset
|
||||
*/
|
||||
public function setPointer($charOffset)
|
||||
{
|
||||
if ($charOffset > $this->_array_size) {
|
||||
$charOffset = $this->_array_size;
|
||||
} elseif ($charOffset < 0) {
|
||||
$charOffset = 0;
|
||||
}
|
||||
$this->_offset = $charOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the stream and reset the internal pointer.
|
||||
*/
|
||||
public function flushContents()
|
||||
{
|
||||
$this->_offset = 0;
|
||||
$this->_array = array();
|
||||
$this->_array_size = 0;
|
||||
}
|
||||
|
||||
private function _reloadBuffer($fp, $len)
|
||||
{
|
||||
if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) {
|
||||
$buf = array();
|
||||
for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
|
||||
$buf[] = self::$_byteMap[$bytes[$i]];
|
||||
}
|
||||
|
||||
return $buf;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function _initializeMaps()
|
||||
{
|
||||
if (!isset(self::$_charMap)) {
|
||||
self::$_charMap = array();
|
||||
for ($byte = 0; $byte < 256; ++$byte) {
|
||||
self::$_charMap[$byte] = chr($byte);
|
||||
}
|
||||
self::$_byteMap = array_flip(self::$_charMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A CharacterStream implementation which stores characters in an internal array.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage CharacterStream
|
||||
* @author Xavier De Cock <xdecock@gmail.com>
|
||||
*/
|
||||
|
||||
class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream
|
||||
{
|
||||
/**
|
||||
* The char reader (lazy-loaded) for the current charset.
|
||||
*
|
||||
* @var Swift_CharacterReader
|
||||
*/
|
||||
private $_charReader;
|
||||
|
||||
/**
|
||||
* A factory for creating CharacterReader instances.
|
||||
*
|
||||
* @var Swift_CharacterReaderFactory
|
||||
*/
|
||||
private $_charReaderFactory;
|
||||
|
||||
/**
|
||||
* The character set this stream is using.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_charset;
|
||||
|
||||
/**
|
||||
* The data's stored as-is.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_datas = '';
|
||||
|
||||
/**
|
||||
* Number of bytes in the stream
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_datasSize = 0;
|
||||
|
||||
/**
|
||||
* Map.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $_map;
|
||||
|
||||
/**
|
||||
* Map Type.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_mapType = 0;
|
||||
|
||||
/**
|
||||
* Number of characters in the stream.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_charCount = 0;
|
||||
|
||||
/**
|
||||
* Position in the stream.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_currentPos = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Swift_CharacterReaderFactory $factory
|
||||
* @param string $charset
|
||||
*/
|
||||
public function __construct(Swift_CharacterReaderFactory $factory, $charset)
|
||||
{
|
||||
$this->setCharacterReaderFactory($factory);
|
||||
$this->setCharacterSet($charset);
|
||||
}
|
||||
|
||||
/* -- Changing parameters of the stream -- */
|
||||
|
||||
/**
|
||||
* Set the character set used in this CharacterStream.
|
||||
*
|
||||
* @param string $charset
|
||||
*/
|
||||
public function setCharacterSet($charset)
|
||||
{
|
||||
$this->_charset = $charset;
|
||||
$this->_charReader = null;
|
||||
$this->_mapType = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CharacterReaderFactory for multi charset support.
|
||||
*
|
||||
* @param Swift_CharacterReaderFactory $factory
|
||||
*/
|
||||
public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
|
||||
{
|
||||
$this->_charReaderFactory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::flushContents()
|
||||
*/
|
||||
public function flushContents()
|
||||
{
|
||||
$this->_datas = null;
|
||||
$this->_map = null;
|
||||
$this->_charCount = 0;
|
||||
$this->_currentPos = 0;
|
||||
$this->_datasSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::importByteStream()
|
||||
*
|
||||
* @param Swift_OutputByteStream $os
|
||||
*/
|
||||
public function importByteStream(Swift_OutputByteStream $os)
|
||||
{
|
||||
$this->flushContents();
|
||||
$blocks=512;
|
||||
$os->setReadPointer(0);
|
||||
while(false!==($read = $os->read($blocks)))
|
||||
$this->write($read);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::importString()
|
||||
*
|
||||
* @param string $string
|
||||
*/
|
||||
public function importString($string)
|
||||
{
|
||||
$this->flushContents();
|
||||
$this->write($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::read()
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read($length)
|
||||
{
|
||||
if ($this->_currentPos>=$this->_charCount) {
|
||||
return false;
|
||||
}
|
||||
$ret=false;
|
||||
$length = ($this->_currentPos+$length > $this->_charCount)
|
||||
? $this->_charCount - $this->_currentPos
|
||||
: $length;
|
||||
switch ($this->_mapType) {
|
||||
case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
|
||||
$len = $length*$this->_map;
|
||||
$ret = substr($this->_datas,
|
||||
$this->_currentPos * $this->_map,
|
||||
$len);
|
||||
$this->_currentPos += $length;
|
||||
break;
|
||||
|
||||
case Swift_CharacterReader::MAP_TYPE_INVALID:
|
||||
$end = $this->_currentPos + $length;
|
||||
$end = $end > $this->_charCount
|
||||
?$this->_charCount
|
||||
:$end;
|
||||
$ret = '';
|
||||
for (; $this->_currentPos < $length; ++$this->_currentPos) {
|
||||
if (isset ($this->_map[$this->_currentPos])) {
|
||||
$ret .= '?';
|
||||
} else {
|
||||
$ret .= $this->_datas[$this->_currentPos];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Swift_CharacterReader::MAP_TYPE_POSITIONS:
|
||||
$end = $this->_currentPos + $length;
|
||||
$end = $end > $this->_charCount
|
||||
?$this->_charCount
|
||||
:$end;
|
||||
$ret = '';
|
||||
$start = 0;
|
||||
if ($this->_currentPos>0) {
|
||||
$start = $this->_map['p'][$this->_currentPos-1];
|
||||
}
|
||||
$to = $start;
|
||||
for (; $this->_currentPos < $end; ++$this->_currentPos) {
|
||||
if (isset($this->_map['i'][$this->_currentPos])) {
|
||||
$ret .= substr($this->_datas, $start, $to - $start).'?';
|
||||
$start = $this->_map['p'][$this->_currentPos];
|
||||
} else {
|
||||
$to = $this->_map['p'][$this->_currentPos];
|
||||
}
|
||||
}
|
||||
$ret .= substr($this->_datas, $start, $to - $start);
|
||||
break;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::readBytes()
|
||||
*
|
||||
* @param integer $length
|
||||
*
|
||||
* @return integer[]
|
||||
*/
|
||||
public function readBytes($length)
|
||||
{
|
||||
$read=$this->read($length);
|
||||
if ($read!==false) {
|
||||
$ret = array_map('ord', str_split($read, 1));
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::setPointer()
|
||||
*
|
||||
* @param integer $charOffset
|
||||
*/
|
||||
public function setPointer($charOffset)
|
||||
{
|
||||
if ($this->_charCount<$charOffset) {
|
||||
$charOffset=$this->_charCount;
|
||||
}
|
||||
$this->_currentPos = $charOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Swift_CharacterStream::write()
|
||||
*
|
||||
* @param string $chars
|
||||
*/
|
||||
public function write($chars)
|
||||
{
|
||||
if (!isset($this->_charReader)) {
|
||||
$this->_charReader = $this->_charReaderFactory->getReaderFor(
|
||||
$this->_charset);
|
||||
$this->_map = array();
|
||||
$this->_mapType = $this->_charReader->getMapType();
|
||||
}
|
||||
$ignored='';
|
||||
$this->_datas .= $chars;
|
||||
$this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored);
|
||||
if ($ignored!==false) {
|
||||
$this->_datasSize=strlen($this->_datas)-strlen($ignored);
|
||||
} else {
|
||||
$this->_datasSize=strlen($this->_datas);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2009 Fabien Potencier <fabien.potencier@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for Spools (implements time and message limits).
|
||||
*
|
||||
* @package Swift
|
||||
* @author Fabien Potencier
|
||||
*/
|
||||
abstract class Swift_ConfigurableSpool implements Swift_Spool
|
||||
{
|
||||
/** The maximum number of messages to send per flush */
|
||||
private $_message_limit;
|
||||
|
||||
/** The time limit per flush */
|
||||
private $_time_limit;
|
||||
|
||||
/**
|
||||
* Sets the maximum number of messages to send per flush.
|
||||
*
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function setMessageLimit($limit)
|
||||
{
|
||||
$this->_message_limit = (int) $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum number of messages to send per flush.
|
||||
*
|
||||
* @return integer The limit
|
||||
*/
|
||||
public function getMessageLimit()
|
||||
{
|
||||
return $this->_message_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time limit (in seconds) per flush.
|
||||
*
|
||||
* @param integer $limit The limit
|
||||
*/
|
||||
public function setTimeLimit($limit)
|
||||
{
|
||||
$this->_time_limit = (int) $limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time limit (in seconds) per flush.
|
||||
*
|
||||
* @return integer The limit
|
||||
*/
|
||||
public function getTimeLimit()
|
||||
{
|
||||
return $this->_time_limit;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,373 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dependency Injection container.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_DependencyContainer
|
||||
{
|
||||
/** Constant for literal value types */
|
||||
const TYPE_VALUE = 0x0001;
|
||||
|
||||
/** Constant for new instance types */
|
||||
const TYPE_INSTANCE = 0x0010;
|
||||
|
||||
/** Constant for shared instance types */
|
||||
const TYPE_SHARED = 0x0100;
|
||||
|
||||
/** Constant for aliases */
|
||||
const TYPE_ALIAS = 0x1000;
|
||||
|
||||
/** Singleton instance */
|
||||
private static $_instance = null;
|
||||
|
||||
/** The data container */
|
||||
private $_store = array();
|
||||
|
||||
/** The current endpoint in the data container */
|
||||
private $_endPoint;
|
||||
|
||||
/**
|
||||
* Constructor should not be used.
|
||||
*
|
||||
* Use {@link getInstance()} instead.
|
||||
*/
|
||||
public function __construct() { }
|
||||
|
||||
/**
|
||||
* Returns a singleton of the DependencyContainer.
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!isset(self::$_instance)) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the names of all items stored in the Container.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listItems()
|
||||
{
|
||||
return array_keys($this->_store);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if an item is registered in this container with the given name.
|
||||
*
|
||||
* @see register()
|
||||
*
|
||||
* @param string $itemName
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function has($itemName)
|
||||
{
|
||||
return array_key_exists($itemName, $this->_store)
|
||||
&& isset($this->_store[$itemName]['lookupType']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the item with the given $itemName.
|
||||
*
|
||||
* @see register()
|
||||
*
|
||||
* @param string $itemName
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws Swift_DependencyException If the dependency is not found
|
||||
*/
|
||||
public function lookup($itemName)
|
||||
{
|
||||
if (!$this->has($itemName)) {
|
||||
throw new Swift_DependencyException(
|
||||
'Cannot lookup dependency "' . $itemName . '" since it is not registered.'
|
||||
);
|
||||
}
|
||||
|
||||
switch ($this->_store[$itemName]['lookupType']) {
|
||||
case self::TYPE_ALIAS:
|
||||
return $this->_createAlias($itemName);
|
||||
case self::TYPE_VALUE:
|
||||
return $this->_getValue($itemName);
|
||||
case self::TYPE_INSTANCE:
|
||||
return $this->_createNewInstance($itemName);
|
||||
case self::TYPE_SHARED:
|
||||
return $this->_createSharedInstance($itemName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an array of arguments passed to the constructor of $itemName.
|
||||
*
|
||||
* @param string $itemName
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function createDependenciesFor($itemName)
|
||||
{
|
||||
$args = array();
|
||||
if (isset($this->_store[$itemName]['args'])) {
|
||||
$args = $this->_resolveArgs($this->_store[$itemName]['args']);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new dependency with $itemName.
|
||||
*
|
||||
* This method returns the current DependencyContainer instance because it
|
||||
* requires the use of the fluid interface to set the specific details for the
|
||||
* dependency.
|
||||
* @see asNewInstanceOf(), asSharedInstanceOf(), asValue()
|
||||
*
|
||||
* @param string $itemName
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function register($itemName)
|
||||
{
|
||||
$this->_store[$itemName] = array();
|
||||
$this->_endPoint =& $this->_store[$itemName];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the previously registered item as a literal value.
|
||||
*
|
||||
* {@link register()} must be called before this will work.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function asValue($value)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
$endPoint['lookupType'] = self::TYPE_VALUE;
|
||||
$endPoint['value'] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the previously registered item as an alias of another item.
|
||||
*
|
||||
* @param string $lookup
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function asAliasOf($lookup)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
$endPoint['lookupType'] = self::TYPE_ALIAS;
|
||||
$endPoint['ref'] = $lookup;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the previously registered item as a new instance of $className.
|
||||
*
|
||||
* {@link register()} must be called before this will work.
|
||||
* Any arguments can be set with {@link withDependencies()},
|
||||
* {@link addConstructorValue()} or {@link addConstructorLookup()}.
|
||||
*
|
||||
* @see withDependencies(), addConstructorValue(), addConstructorLookup()
|
||||
*
|
||||
* @param string $className
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function asNewInstanceOf($className)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
$endPoint['lookupType'] = self::TYPE_INSTANCE;
|
||||
$endPoint['className'] = $className;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the previously registered item as a shared instance of $className.
|
||||
*
|
||||
* {@link register()} must be called before this will work.
|
||||
*
|
||||
* @param string $className
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function asSharedInstanceOf($className)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
$endPoint['lookupType'] = self::TYPE_SHARED;
|
||||
$endPoint['className'] = $className;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a list of injected dependencies for the previously registered item.
|
||||
*
|
||||
* This method takes an array of lookup names.
|
||||
*
|
||||
* @see addConstructorValue(), addConstructorLookup()
|
||||
*
|
||||
* @param array $lookups
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function withDependencies(array $lookups)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
$endPoint['args'] = array();
|
||||
foreach ($lookups as $lookup) {
|
||||
$this->addConstructorLookup($lookup);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a literal (non looked up) value for the constructor of the
|
||||
* previously registered item.
|
||||
*
|
||||
* @see withDependencies(), addConstructorLookup()
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function addConstructorValue($value)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
if (!isset($endPoint['args'])) {
|
||||
$endPoint['args'] = array();
|
||||
}
|
||||
$endPoint['args'][] = array('type' => 'value', 'item' => $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a dependency lookup for the constructor of the previously
|
||||
* registered item.
|
||||
*
|
||||
* @see withDependencies(), addConstructorValue()
|
||||
*
|
||||
* @param string $lookup
|
||||
*
|
||||
* @return Swift_DependencyContainer
|
||||
*/
|
||||
public function addConstructorLookup($lookup)
|
||||
{
|
||||
$endPoint =& $this->_getEndPoint();
|
||||
if (!isset($this->_endPoint['args'])) {
|
||||
$endPoint['args'] = array();
|
||||
}
|
||||
$endPoint['args'][] = array('type' => 'lookup', 'item' => $lookup);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// -- Private methods
|
||||
|
||||
/** Get the literal value with $itemName */
|
||||
private function _getValue($itemName)
|
||||
{
|
||||
return $this->_store[$itemName]['value'];
|
||||
}
|
||||
|
||||
/** Resolve an alias to another item */
|
||||
private function _createAlias($itemName)
|
||||
{
|
||||
return $this->lookup($this->_store[$itemName]['ref']);
|
||||
}
|
||||
|
||||
/** Create a fresh instance of $itemName */
|
||||
private function _createNewInstance($itemName)
|
||||
{
|
||||
$reflector = new ReflectionClass($this->_store[$itemName]['className']);
|
||||
if ($reflector->getConstructor()) {
|
||||
return $reflector->newInstanceArgs(
|
||||
$this->createDependenciesFor($itemName)
|
||||
);
|
||||
} else {
|
||||
return $reflector->newInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/** Create and register a shared instance of $itemName */
|
||||
private function _createSharedInstance($itemName)
|
||||
{
|
||||
if (!isset($this->_store[$itemName]['instance'])) {
|
||||
$this->_store[$itemName]['instance'] = $this->_createNewInstance($itemName);
|
||||
}
|
||||
|
||||
return $this->_store[$itemName]['instance'];
|
||||
}
|
||||
|
||||
/** Get the current endpoint in the store */
|
||||
private function &_getEndPoint()
|
||||
{
|
||||
if (!isset($this->_endPoint)) {
|
||||
throw new BadMethodCallException(
|
||||
'Component must first be registered by calling register()'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->_endPoint;
|
||||
}
|
||||
|
||||
/** Get an argument list with dependencies resolved */
|
||||
private function _resolveArgs(array $args)
|
||||
{
|
||||
$resolved = array();
|
||||
foreach ($args as $argDefinition) {
|
||||
switch ($argDefinition['type']) {
|
||||
case 'lookup':
|
||||
$resolved[] = $this->_lookupRecursive($argDefinition['item']);
|
||||
break;
|
||||
case 'value':
|
||||
$resolved[] = $argDefinition['item'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
/** Resolve a single dependency with an collections */
|
||||
private function _lookupRecursive($item)
|
||||
{
|
||||
if (is_array($item)) {
|
||||
$collection = array();
|
||||
foreach ($item as $k => $v) {
|
||||
$collection[$k] = $this->_lookupRecursive($v);
|
||||
}
|
||||
|
||||
return $collection;
|
||||
} else {
|
||||
return $this->lookup($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DependencyException gets thrown when a requested dependency is missing.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_DependencyException extends Swift_SwiftException
|
||||
{
|
||||
/**
|
||||
* Create a new DependencyException with $message.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct($message)
|
||||
{
|
||||
parent::__construct($message);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An embedded file, in a multipart message.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_EmbeddedFile extends Swift_Mime_EmbeddedFile
|
||||
{
|
||||
/**
|
||||
* Create a new EmbeddedFile.
|
||||
*
|
||||
* Details may be optionally provided to the constructor.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $data
|
||||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*/
|
||||
public function __construct($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Mime_EmbeddedFile::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('mime.embeddedfile')
|
||||
);
|
||||
|
||||
$this->setBody($data);
|
||||
$this->setFilename($filename);
|
||||
if ($contentType) {
|
||||
$this->setContentType($contentType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new EmbeddedFile.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $data
|
||||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*
|
||||
* @return Swift_Mime_EmbeddedFile
|
||||
*/
|
||||
public static function newInstance($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
return new self($data, $filename, $contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new EmbeddedFile from a filesystem path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Swift_Mime_EmbeddedFile
|
||||
*/
|
||||
public static function fromPath($path)
|
||||
{
|
||||
return self::newInstance()->setFile(
|
||||
new Swift_ByteStream_FileByteStream($path)
|
||||
);
|
||||
}
|
||||
}
|
||||
29
public/include/lib/swiftmailer/classes/Swift/Encoder.php
Normal file
29
public/include/lib/swiftmailer/classes/Swift/Encoder.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for all Encoder schemes.
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Encoder extends Swift_Mime_CharsetObserver
|
||||
{
|
||||
/**
|
||||
* Encode a given string to produce an encoded string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $firstLineOffset if first line needs to be shorter
|
||||
* @param integer $maxLineLength - 0 indicates the default length for this encoding
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0);
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles Base 64 Encoding in Swift Mailer.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Encoder_Base64Encoder implements Swift_Encoder
|
||||
{
|
||||
/**
|
||||
* Takes an unencoded string and produces a Base64 encoded string from it.
|
||||
*
|
||||
* Base64 encoded strings have a maximum line length of 76 characters.
|
||||
* If the first line needs to be shorter, indicate the difference with
|
||||
* $firstLineOffset.
|
||||
*
|
||||
* @param string $string to encode
|
||||
* @param integer $firstLineOffset
|
||||
* @param integer $maxLineLength optional, 0 indicates the default of 76 bytes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
|
||||
{
|
||||
if (0 >= $maxLineLength || 76 < $maxLineLength) {
|
||||
$maxLineLength = 76;
|
||||
}
|
||||
|
||||
$encodedString = base64_encode($string);
|
||||
$firstLine = '';
|
||||
|
||||
if (0 != $firstLineOffset) {
|
||||
$firstLine = substr(
|
||||
$encodedString, 0, $maxLineLength - $firstLineOffset
|
||||
) . "\r\n";
|
||||
$encodedString = substr(
|
||||
$encodedString, $maxLineLength - $firstLineOffset
|
||||
);
|
||||
}
|
||||
|
||||
return $firstLine . trim(chunk_split($encodedString, $maxLineLength, "\r\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Does nothing.
|
||||
*/
|
||||
public function charsetChanged($charset)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,286 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles Quoted Printable (QP) Encoding in Swift Mailer.
|
||||
*
|
||||
* Possibly the most accurate RFC 2045 QP implementation found in PHP.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Encoder_QpEncoder implements Swift_Encoder
|
||||
{
|
||||
/**
|
||||
* The CharacterStream used for reading characters (as opposed to bytes).
|
||||
*
|
||||
* @var Swift_CharacterStream
|
||||
*/
|
||||
protected $_charStream;
|
||||
|
||||
/**
|
||||
* A filter used if input should be canonicalized.
|
||||
*
|
||||
* @var Swift_StreamFilter
|
||||
*/
|
||||
protected $_filter;
|
||||
|
||||
/**
|
||||
* Pre-computed QP for HUGE optimization.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $_qpMap = array(
|
||||
0 => '=00', 1 => '=01', 2 => '=02', 3 => '=03', 4 => '=04',
|
||||
5 => '=05', 6 => '=06', 7 => '=07', 8 => '=08', 9 => '=09',
|
||||
10 => '=0A', 11 => '=0B', 12 => '=0C', 13 => '=0D', 14 => '=0E',
|
||||
15 => '=0F', 16 => '=10', 17 => '=11', 18 => '=12', 19 => '=13',
|
||||
20 => '=14', 21 => '=15', 22 => '=16', 23 => '=17', 24 => '=18',
|
||||
25 => '=19', 26 => '=1A', 27 => '=1B', 28 => '=1C', 29 => '=1D',
|
||||
30 => '=1E', 31 => '=1F', 32 => '=20', 33 => '=21', 34 => '=22',
|
||||
35 => '=23', 36 => '=24', 37 => '=25', 38 => '=26', 39 => '=27',
|
||||
40 => '=28', 41 => '=29', 42 => '=2A', 43 => '=2B', 44 => '=2C',
|
||||
45 => '=2D', 46 => '=2E', 47 => '=2F', 48 => '=30', 49 => '=31',
|
||||
50 => '=32', 51 => '=33', 52 => '=34', 53 => '=35', 54 => '=36',
|
||||
55 => '=37', 56 => '=38', 57 => '=39', 58 => '=3A', 59 => '=3B',
|
||||
60 => '=3C', 61 => '=3D', 62 => '=3E', 63 => '=3F', 64 => '=40',
|
||||
65 => '=41', 66 => '=42', 67 => '=43', 68 => '=44', 69 => '=45',
|
||||
70 => '=46', 71 => '=47', 72 => '=48', 73 => '=49', 74 => '=4A',
|
||||
75 => '=4B', 76 => '=4C', 77 => '=4D', 78 => '=4E', 79 => '=4F',
|
||||
80 => '=50', 81 => '=51', 82 => '=52', 83 => '=53', 84 => '=54',
|
||||
85 => '=55', 86 => '=56', 87 => '=57', 88 => '=58', 89 => '=59',
|
||||
90 => '=5A', 91 => '=5B', 92 => '=5C', 93 => '=5D', 94 => '=5E',
|
||||
95 => '=5F', 96 => '=60', 97 => '=61', 98 => '=62', 99 => '=63',
|
||||
100 => '=64', 101 => '=65', 102 => '=66', 103 => '=67', 104 => '=68',
|
||||
105 => '=69', 106 => '=6A', 107 => '=6B', 108 => '=6C', 109 => '=6D',
|
||||
110 => '=6E', 111 => '=6F', 112 => '=70', 113 => '=71', 114 => '=72',
|
||||
115 => '=73', 116 => '=74', 117 => '=75', 118 => '=76', 119 => '=77',
|
||||
120 => '=78', 121 => '=79', 122 => '=7A', 123 => '=7B', 124 => '=7C',
|
||||
125 => '=7D', 126 => '=7E', 127 => '=7F', 128 => '=80', 129 => '=81',
|
||||
130 => '=82', 131 => '=83', 132 => '=84', 133 => '=85', 134 => '=86',
|
||||
135 => '=87', 136 => '=88', 137 => '=89', 138 => '=8A', 139 => '=8B',
|
||||
140 => '=8C', 141 => '=8D', 142 => '=8E', 143 => '=8F', 144 => '=90',
|
||||
145 => '=91', 146 => '=92', 147 => '=93', 148 => '=94', 149 => '=95',
|
||||
150 => '=96', 151 => '=97', 152 => '=98', 153 => '=99', 154 => '=9A',
|
||||
155 => '=9B', 156 => '=9C', 157 => '=9D', 158 => '=9E', 159 => '=9F',
|
||||
160 => '=A0', 161 => '=A1', 162 => '=A2', 163 => '=A3', 164 => '=A4',
|
||||
165 => '=A5', 166 => '=A6', 167 => '=A7', 168 => '=A8', 169 => '=A9',
|
||||
170 => '=AA', 171 => '=AB', 172 => '=AC', 173 => '=AD', 174 => '=AE',
|
||||
175 => '=AF', 176 => '=B0', 177 => '=B1', 178 => '=B2', 179 => '=B3',
|
||||
180 => '=B4', 181 => '=B5', 182 => '=B6', 183 => '=B7', 184 => '=B8',
|
||||
185 => '=B9', 186 => '=BA', 187 => '=BB', 188 => '=BC', 189 => '=BD',
|
||||
190 => '=BE', 191 => '=BF', 192 => '=C0', 193 => '=C1', 194 => '=C2',
|
||||
195 => '=C3', 196 => '=C4', 197 => '=C5', 198 => '=C6', 199 => '=C7',
|
||||
200 => '=C8', 201 => '=C9', 202 => '=CA', 203 => '=CB', 204 => '=CC',
|
||||
205 => '=CD', 206 => '=CE', 207 => '=CF', 208 => '=D0', 209 => '=D1',
|
||||
210 => '=D2', 211 => '=D3', 212 => '=D4', 213 => '=D5', 214 => '=D6',
|
||||
215 => '=D7', 216 => '=D8', 217 => '=D9', 218 => '=DA', 219 => '=DB',
|
||||
220 => '=DC', 221 => '=DD', 222 => '=DE', 223 => '=DF', 224 => '=E0',
|
||||
225 => '=E1', 226 => '=E2', 227 => '=E3', 228 => '=E4', 229 => '=E5',
|
||||
230 => '=E6', 231 => '=E7', 232 => '=E8', 233 => '=E9', 234 => '=EA',
|
||||
235 => '=EB', 236 => '=EC', 237 => '=ED', 238 => '=EE', 239 => '=EF',
|
||||
240 => '=F0', 241 => '=F1', 242 => '=F2', 243 => '=F3', 244 => '=F4',
|
||||
245 => '=F5', 246 => '=F6', 247 => '=F7', 248 => '=F8', 249 => '=F9',
|
||||
250 => '=FA', 251 => '=FB', 252 => '=FC', 253 => '=FD', 254 => '=FE',
|
||||
255 => '=FF'
|
||||
);
|
||||
|
||||
protected static $_safeMapShare = array();
|
||||
|
||||
/**
|
||||
* A map of non-encoded ascii characters.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $_safeMap = array();
|
||||
|
||||
/**
|
||||
* Creates a new QpEncoder for the given CharacterStream.
|
||||
*
|
||||
* @param Swift_CharacterStream $charStream to use for reading characters
|
||||
* @param Swift_StreamFilter $filter if input should be canonicalized
|
||||
*/
|
||||
public function __construct(Swift_CharacterStream $charStream, Swift_StreamFilter $filter = null)
|
||||
{
|
||||
$this->_charStream = $charStream;
|
||||
if (!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) {
|
||||
$this->initSafeMap();
|
||||
self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap;
|
||||
} else {
|
||||
$this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()];
|
||||
}
|
||||
$this->_filter = $filter;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
return array('_charStream', '_filter');
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
if (!isset(self::$_safeMapShare[$this->getSafeMapShareId()])) {
|
||||
$this->initSafeMap();
|
||||
self::$_safeMapShare[$this->getSafeMapShareId()] = $this->_safeMap;
|
||||
} else {
|
||||
$this->_safeMap = self::$_safeMapShare[$this->getSafeMapShareId()];
|
||||
}
|
||||
}
|
||||
|
||||
protected function getSafeMapShareId()
|
||||
{
|
||||
return get_class($this);
|
||||
}
|
||||
|
||||
protected function initSafeMap()
|
||||
{
|
||||
foreach (array_merge(
|
||||
array(0x09, 0x20), range(0x21, 0x3C), range(0x3E, 0x7E)) as $byte)
|
||||
{
|
||||
$this->_safeMap[$byte] = chr($byte);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an unencoded string and produces a QP encoded string from it.
|
||||
*
|
||||
* QP encoded strings have a maximum line length of 76 characters.
|
||||
* If the first line needs to be shorter, indicate the difference with
|
||||
* $firstLineOffset.
|
||||
*
|
||||
* @param string $string to encode
|
||||
* @param integer $firstLineOffset, optional
|
||||
* @param integer $maxLineLength, optional 0 indicates the default of 76 chars
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
|
||||
{
|
||||
if ($maxLineLength > 76 || $maxLineLength <= 0) {
|
||||
$maxLineLength = 76;
|
||||
}
|
||||
|
||||
$thisLineLength = $maxLineLength - $firstLineOffset;
|
||||
|
||||
$lines = array();
|
||||
$lNo = 0;
|
||||
$lines[$lNo] = '';
|
||||
$currentLine =& $lines[$lNo++];
|
||||
$size=$lineLen=0;
|
||||
|
||||
$this->_charStream->flushContents();
|
||||
$this->_charStream->importString($string);
|
||||
|
||||
// Fetching more than 4 chars at one is slower, as is fetching fewer bytes
|
||||
// Conveniently 4 chars is the UTF-8 safe number since UTF-8 has up to 6
|
||||
// bytes per char and (6 * 4 * 3 = 72 chars per line) * =NN is 3 bytes
|
||||
while (false !== $bytes = $this->_nextSequence()) {
|
||||
// If we're filtering the input
|
||||
if (isset($this->_filter)) {
|
||||
// If we can't filter because we need more bytes
|
||||
while ($this->_filter->shouldBuffer($bytes)) {
|
||||
// Then collect bytes into the buffer
|
||||
if (false === $moreBytes = $this->_nextSequence(1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($moreBytes as $b) {
|
||||
$bytes[] = $b;
|
||||
}
|
||||
}
|
||||
// And filter them
|
||||
$bytes = $this->_filter->filter($bytes);
|
||||
}
|
||||
|
||||
$enc = $this->_encodeByteSequence($bytes, $size);
|
||||
if ($currentLine && $lineLen+$size >= $thisLineLength) {
|
||||
$lines[$lNo] = '';
|
||||
$currentLine =& $lines[$lNo++];
|
||||
$thisLineLength = $maxLineLength;
|
||||
$lineLen=0;
|
||||
}
|
||||
$lineLen+=$size;
|
||||
$currentLine .= $enc;
|
||||
}
|
||||
|
||||
return $this->_standardize(implode("=\r\n", $lines));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the charset used.
|
||||
*
|
||||
* @param string $charset
|
||||
*/
|
||||
public function charsetChanged($charset)
|
||||
{
|
||||
$this->_charStream->setCharacterSet($charset);
|
||||
}
|
||||
|
||||
// -- Protected methods
|
||||
|
||||
/**
|
||||
* Encode the given byte array into a verbatim QP form.
|
||||
*
|
||||
* @param integer[] $bytes
|
||||
* @param integer $size
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _encodeByteSequence(array $bytes, &$size)
|
||||
{
|
||||
$ret = '';
|
||||
$size=0;
|
||||
foreach ($bytes as $b) {
|
||||
if (isset($this->_safeMap[$b])) {
|
||||
$ret .= $this->_safeMap[$b];
|
||||
++$size;
|
||||
} else {
|
||||
$ret .= self::$_qpMap[$b];
|
||||
$size+=3;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next sequence of bytes to read from the char stream.
|
||||
*
|
||||
* @param integer $size number of bytes to read
|
||||
*
|
||||
* @return integer[]
|
||||
*/
|
||||
protected function _nextSequence($size = 4)
|
||||
{
|
||||
return $this->_charStream->readBytes($size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure CRLF is correct and HT/SPACE are in valid places.
|
||||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _standardize($string)
|
||||
{
|
||||
$string = str_replace(array("\t=0D=0A", " =0D=0A", "=0D=0A"),
|
||||
array("=09\r\n", "=20\r\n", "\r\n"), $string
|
||||
);
|
||||
switch ($end = ord(substr($string, -1))) {
|
||||
case 0x09:
|
||||
case 0x20:
|
||||
$string = substr_replace($string, self::$_qpMap[$end], -1);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles RFC 2231 specified Encoding in Swift Mailer.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Encoder_Rfc2231Encoder implements Swift_Encoder
|
||||
{
|
||||
/**
|
||||
* A character stream to use when reading a string as characters instead of bytes.
|
||||
*
|
||||
* @var Swift_CharacterStream
|
||||
*/
|
||||
private $_charStream;
|
||||
|
||||
/**
|
||||
* Creates a new Rfc2231Encoder using the given character stream instance.
|
||||
*
|
||||
* @param Swift_CharacterStream
|
||||
*/
|
||||
public function __construct(Swift_CharacterStream $charStream)
|
||||
{
|
||||
$this->_charStream = $charStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an unencoded string and produces a string encoded according to
|
||||
* RFC 2231 from it.
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $firstLineOffset
|
||||
* @param integer $maxLineLength optional, 0 indicates the default of 75 bytes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function encodeString($string, $firstLineOffset = 0, $maxLineLength = 0)
|
||||
{
|
||||
$lines = array(); $lineCount = 0;
|
||||
$lines[] = '';
|
||||
$currentLine =& $lines[$lineCount++];
|
||||
|
||||
if (0 >= $maxLineLength) {
|
||||
$maxLineLength = 75;
|
||||
}
|
||||
|
||||
$this->_charStream->flushContents();
|
||||
$this->_charStream->importString($string);
|
||||
|
||||
$thisLineLength = $maxLineLength - $firstLineOffset;
|
||||
|
||||
while (false !== $char = $this->_charStream->read(4)) {
|
||||
$encodedChar = rawurlencode($char);
|
||||
if (0 != strlen($currentLine)
|
||||
&& strlen($currentLine . $encodedChar) > $thisLineLength)
|
||||
{
|
||||
$lines[] = '';
|
||||
$currentLine =& $lines[$lineCount++];
|
||||
$thisLineLength = $maxLineLength;
|
||||
}
|
||||
$currentLine .= $encodedChar;
|
||||
}
|
||||
|
||||
return implode("\r\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the charset used.
|
||||
*
|
||||
* @param string $charset
|
||||
*/
|
||||
public function charsetChanged($charset)
|
||||
{
|
||||
$this->_charStream->setCharacterSet($charset);
|
||||
}
|
||||
}
|
||||
66
public/include/lib/swiftmailer/classes/Swift/Encoding.php
Normal file
66
public/include/lib/swiftmailer/classes/Swift/Encoding.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides quick access to each encoding type.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Encoder
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Encoding
|
||||
{
|
||||
/**
|
||||
* Get the Encoder that provides 7-bit encoding.
|
||||
*
|
||||
* @return Swift_Mime_ContentEncoder
|
||||
*/
|
||||
public static function get7BitEncoding()
|
||||
{
|
||||
return self::_lookup('mime.7bitcontentencoder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Encoder that provides 8-bit encoding.
|
||||
*
|
||||
* @return Swift_Mime_ContentEncoder
|
||||
*/
|
||||
public static function get8BitEncoding()
|
||||
{
|
||||
return self::_lookup('mime.8bitcontentencoder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Encoder that provides Quoted-Printable (QP) encoding.
|
||||
*
|
||||
* @return Swift_Mime_ContentEncoder
|
||||
*/
|
||||
public static function getQpEncoding()
|
||||
{
|
||||
return self::_lookup('mime.qpcontentencoder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Encoder that provides Base64 encoding.
|
||||
*
|
||||
* @return Swift_Mime_ContentEncoder
|
||||
*/
|
||||
public static function getBase64Encoding()
|
||||
{
|
||||
return self::_lookup('mime.base64contentencoder');
|
||||
}
|
||||
|
||||
// -- Private Static Methods
|
||||
|
||||
private static function _lookup($key)
|
||||
{
|
||||
return Swift_DependencyContainer::getInstance()->lookup($key);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generated when a command is sent over an SMTP connection.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_CommandEvent extends Swift_Events_EventObject
|
||||
{
|
||||
/**
|
||||
* The command sent to the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_command;
|
||||
|
||||
/**
|
||||
* An array of codes which a successful response will contain.
|
||||
*
|
||||
* @var integer[]
|
||||
*/
|
||||
private $_successCodes = array();
|
||||
|
||||
/**
|
||||
* Create a new CommandEvent for $source with $command.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param string $command
|
||||
* @param array $successCodes
|
||||
*/
|
||||
public function __construct(Swift_Transport $source, $command, $successCodes = array())
|
||||
{
|
||||
parent::__construct($source);
|
||||
$this->_command = $command;
|
||||
$this->_successCodes = $successCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command which was sent to the server.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCommand()
|
||||
{
|
||||
return $this->_command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the numeric response codes which indicate success for this command.
|
||||
*
|
||||
* @return integer[]
|
||||
*/
|
||||
public function getSuccessCodes()
|
||||
{
|
||||
return $this->_successCodes;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Listens for Transports to send commands to the server.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_CommandListener extends Swift_Events_EventListener
|
||||
{
|
||||
/**
|
||||
* Invoked immediately following a command being sent.
|
||||
*
|
||||
* @param Swift_Events_CommandEvent $evt
|
||||
*/
|
||||
public function commandSent(Swift_Events_CommandEvent $evt);
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The minimum interface for an Event.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_Event
|
||||
{
|
||||
/**
|
||||
* Get the source object of this event.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getSource();
|
||||
|
||||
/**
|
||||
* Prevent this Event from bubbling any further up the stack.
|
||||
*
|
||||
* @param boolean $cancel, optional
|
||||
*/
|
||||
public function cancelBubble($cancel = true);
|
||||
|
||||
/**
|
||||
* Returns true if this Event will not bubble any further up the stack.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function bubbleCancelled();
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for the EventDispatcher which handles the event dispatching layer.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_EventDispatcher
|
||||
{
|
||||
/**
|
||||
* Create a new SendEvent for $source and $message.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param Swift_Mime_Message
|
||||
*
|
||||
* @return Swift_Events_SendEvent
|
||||
*/
|
||||
public function createSendEvent(Swift_Transport $source, Swift_Mime_Message $message);
|
||||
|
||||
/**
|
||||
* Create a new CommandEvent for $source and $command.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param string $command That will be executed
|
||||
* @param array $successCodes That are needed
|
||||
*
|
||||
* @return Swift_Events_CommandEvent
|
||||
*/
|
||||
public function createCommandEvent(Swift_Transport $source, $command, $successCodes = array());
|
||||
|
||||
/**
|
||||
* Create a new ResponseEvent for $source and $response.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param string $response
|
||||
* @param boolean $valid If the response is valid
|
||||
*
|
||||
* @return Swift_Events_ResponseEvent
|
||||
*/
|
||||
public function createResponseEvent(Swift_Transport $source, $response, $valid);
|
||||
|
||||
/**
|
||||
* Create a new TransportChangeEvent for $source.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
*
|
||||
* @return Swift_Events_TransportChangeEvent
|
||||
*/
|
||||
public function createTransportChangeEvent(Swift_Transport $source);
|
||||
|
||||
/**
|
||||
* Create a new TransportExceptionEvent for $source.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param Swift_TransportException $ex
|
||||
*
|
||||
* @return Swift_Events_TransportExceptionEvent
|
||||
*/
|
||||
public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex);
|
||||
|
||||
/**
|
||||
* Bind an event listener to this dispatcher.
|
||||
*
|
||||
* @param Swift_Events_EventListener $listener
|
||||
*/
|
||||
public function bindEventListener(Swift_Events_EventListener $listener);
|
||||
|
||||
/**
|
||||
* Dispatch the given Event to all suitable listeners.
|
||||
*
|
||||
* @param Swift_Events_EventObject $evt
|
||||
* @param string $target method
|
||||
*/
|
||||
public function dispatchEvent(Swift_Events_EventObject $evt, $target);
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An identity interface which all EventListeners must extend.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_EventListener
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A base Event which all Event classes inherit from.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_EventObject implements Swift_Events_Event
|
||||
{
|
||||
/** The source of this Event */
|
||||
private $_source;
|
||||
|
||||
/** The state of this Event (should it bubble up the stack?) */
|
||||
private $_bubbleCancelled = false;
|
||||
|
||||
/**
|
||||
* Create a new EventObject originating at $source.
|
||||
*
|
||||
* @param object $source
|
||||
*/
|
||||
public function __construct($source)
|
||||
{
|
||||
$this->_source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source object of this event.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getSource()
|
||||
{
|
||||
return $this->_source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent this Event from bubbling any further up the stack.
|
||||
*
|
||||
* @param boolean $cancel, optional
|
||||
*/
|
||||
public function cancelBubble($cancel = true)
|
||||
{
|
||||
$this->_bubbleCancelled = $cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this Event will not bubble any further up the stack.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function bubbleCancelled()
|
||||
{
|
||||
return $this->_bubbleCancelled;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generated when a response is received on a SMTP connection.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_ResponseEvent extends Swift_Events_EventObject
|
||||
{
|
||||
/**
|
||||
* The overall result.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_valid;
|
||||
|
||||
/**
|
||||
* The response received from the server.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_response;
|
||||
|
||||
/**
|
||||
* Create a new ResponseEvent for $source and $response.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param string $response
|
||||
* @param boolean $valid
|
||||
*/
|
||||
public function __construct(Swift_Transport $source, $response, $valid = false)
|
||||
{
|
||||
parent::__construct($source);
|
||||
$this->_response = $response;
|
||||
$this->_valid = $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response which was received from the server.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->_response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the success status of this Event.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid()
|
||||
{
|
||||
return $this->_valid;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Listens for responses from a remote SMTP server.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_ResponseListener extends Swift_Events_EventListener
|
||||
{
|
||||
/**
|
||||
* Invoked immediately following a response coming back.
|
||||
*
|
||||
* @param Swift_Events_ResponseEvent $evt
|
||||
*/
|
||||
public function responseReceived(Swift_Events_ResponseEvent $evt);
|
||||
}
|
||||
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generated when a message is being sent.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_SendEvent extends Swift_Events_EventObject
|
||||
{
|
||||
/** Sending has yet to occur */
|
||||
const RESULT_PENDING = 0x0001;
|
||||
|
||||
/** Sending was successful */
|
||||
const RESULT_SUCCESS = 0x0010;
|
||||
|
||||
/** Sending worked, but there were some failures */
|
||||
const RESULT_TENTATIVE = 0x0100;
|
||||
|
||||
/** Sending failed */
|
||||
const RESULT_FAILED = 0x1000;
|
||||
|
||||
/**
|
||||
* The Message being sent.
|
||||
*
|
||||
* @var Swift_Mime_Message
|
||||
*/
|
||||
private $_message;
|
||||
|
||||
/**
|
||||
* Any recipients which failed after sending.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $_failedRecipients = array();
|
||||
|
||||
/**
|
||||
* The overall result as a bitmask from the class constants.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $_result;
|
||||
|
||||
/**
|
||||
* Create a new SendEvent for $source and $message.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param Swift_Mime_Message $message
|
||||
*/
|
||||
public function __construct(Swift_Transport $source, Swift_Mime_Message $message)
|
||||
{
|
||||
parent::__construct($source);
|
||||
$this->_message = $message;
|
||||
$this->_result = self::RESULT_PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Transport used to send the Message.
|
||||
*
|
||||
* @return Swift_Transport
|
||||
*/
|
||||
public function getTransport()
|
||||
{
|
||||
return $this->getSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Message being sent.
|
||||
*
|
||||
* @return Swift_Mime_Message
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the array of addresses that failed in sending.
|
||||
*
|
||||
* @param array $recipients
|
||||
*/
|
||||
public function setFailedRecipients($recipients)
|
||||
{
|
||||
$this->_failedRecipients = $recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an recipient addresses which were not accepted for delivery.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFailedRecipients()
|
||||
{
|
||||
return $this->_failedRecipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the result of sending.
|
||||
*
|
||||
* @param integer $result
|
||||
*/
|
||||
public function setResult($result)
|
||||
{
|
||||
$this->_result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result of this Event.
|
||||
*
|
||||
* The return value is a bitmask from
|
||||
* {@see RESULT_PENDING, RESULT_SUCCESS, RESULT_TENTATIVE, RESULT_FAILED}
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getResult()
|
||||
{
|
||||
return $this->_result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Listens for Messages being sent from within the Transport system.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_SendListener extends Swift_Events_EventListener
|
||||
{
|
||||
/**
|
||||
* Invoked immediately before the Message is sent.
|
||||
*
|
||||
* @param Swift_Events_SendEvent $evt
|
||||
*/
|
||||
public function beforeSendPerformed(Swift_Events_SendEvent $evt);
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Message is sent.
|
||||
*
|
||||
* @param Swift_Events_SendEvent $evt
|
||||
*/
|
||||
public function sendPerformed(Swift_Events_SendEvent $evt);
|
||||
}
|
||||
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The EventDispatcher which handles the event dispatching layer.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_SimpleEventDispatcher implements Swift_Events_EventDispatcher
|
||||
{
|
||||
/** A map of event types to their associated listener types */
|
||||
private $_eventMap = array();
|
||||
|
||||
/** Event listeners bound to this dispatcher */
|
||||
private $_listeners = array();
|
||||
|
||||
/** Listeners queued to have an Event bubbled up the stack to them */
|
||||
private $_bubbleQueue = array();
|
||||
|
||||
/**
|
||||
* Create a new EventDispatcher.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->_eventMap = array(
|
||||
'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener',
|
||||
'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener',
|
||||
'Swift_Events_SendEvent' => 'Swift_Events_SendListener',
|
||||
'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener',
|
||||
'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SendEvent for $source and $message.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param Swift_Mime_Message
|
||||
*
|
||||
* @return Swift_Events_SendEvent
|
||||
*/
|
||||
public function createSendEvent(Swift_Transport $source, Swift_Mime_Message $message)
|
||||
{
|
||||
return new Swift_Events_SendEvent($source, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CommandEvent for $source and $command.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param string $command That will be executed
|
||||
* @param array $successCodes That are needed
|
||||
*
|
||||
* @return Swift_Events_CommandEvent
|
||||
*/
|
||||
public function createCommandEvent(Swift_Transport $source, $command, $successCodes = array())
|
||||
{
|
||||
return new Swift_Events_CommandEvent($source, $command, $successCodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ResponseEvent for $source and $response.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param string $response
|
||||
* @param boolean $valid If the response is valid
|
||||
*
|
||||
* @return Swift_Events_ResponseEvent
|
||||
*/
|
||||
public function createResponseEvent(Swift_Transport $source, $response, $valid)
|
||||
{
|
||||
return new Swift_Events_ResponseEvent($source, $response, $valid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TransportChangeEvent for $source.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
*
|
||||
* @return Swift_Events_TransportChangeEvent
|
||||
*/
|
||||
public function createTransportChangeEvent(Swift_Transport $source)
|
||||
{
|
||||
return new Swift_Events_TransportChangeEvent($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new TransportExceptionEvent for $source.
|
||||
*
|
||||
* @param Swift_Transport $source
|
||||
* @param Swift_TransportException $ex
|
||||
*
|
||||
* @return Swift_Events_TransportExceptionEvent
|
||||
*/
|
||||
public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex)
|
||||
{
|
||||
return new Swift_Events_TransportExceptionEvent($source, $ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind an event listener to this dispatcher.
|
||||
*
|
||||
* @param Swift_Events_EventListener $listener
|
||||
*/
|
||||
public function bindEventListener(Swift_Events_EventListener $listener)
|
||||
{
|
||||
foreach ($this->_listeners as $l) {
|
||||
// Already loaded
|
||||
if ($l === $listener) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->_listeners[] = $listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the given Event to all suitable listeners.
|
||||
*
|
||||
* @param Swift_Events_EventObject $evt
|
||||
* @param string $target method
|
||||
*/
|
||||
public function dispatchEvent(Swift_Events_EventObject $evt, $target)
|
||||
{
|
||||
$this->_prepareBubbleQueue($evt);
|
||||
$this->_bubble($evt, $target);
|
||||
}
|
||||
|
||||
// -- Private methods
|
||||
|
||||
/** Queue listeners on a stack ready for $evt to be bubbled up it */
|
||||
private function _prepareBubbleQueue(Swift_Events_EventObject $evt)
|
||||
{
|
||||
$this->_bubbleQueue = array();
|
||||
$evtClass = get_class($evt);
|
||||
foreach ($this->_listeners as $listener) {
|
||||
if (array_key_exists($evtClass, $this->_eventMap)
|
||||
&& ($listener instanceof $this->_eventMap[$evtClass]))
|
||||
{
|
||||
$this->_bubbleQueue[] = $listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Bubble $evt up the stack calling $target() on each listener */
|
||||
private function _bubble(Swift_Events_EventObject $evt, $target)
|
||||
{
|
||||
if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue)) {
|
||||
$listener->$target($evt);
|
||||
$this->_bubble($evt, $target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generated when the state of a Transport is changed (i.e. stopped/started).
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_TransportChangeEvent extends Swift_Events_EventObject
|
||||
{
|
||||
/**
|
||||
* Get the Transport.
|
||||
*
|
||||
* @return Swift_Transport
|
||||
*/
|
||||
public function getTransport()
|
||||
{
|
||||
return $this->getSource();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Listens for changes within the Transport system.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_TransportChangeListener extends Swift_Events_EventListener
|
||||
{
|
||||
/**
|
||||
* Invoked just before a Transport is started.
|
||||
*
|
||||
* @param Swift_Events_TransportChangeEvent $evt
|
||||
*/
|
||||
public function beforeTransportStarted(Swift_Events_TransportChangeEvent $evt);
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Transport is started.
|
||||
*
|
||||
* @param Swift_Events_TransportChangeEvent $evt
|
||||
*/
|
||||
public function transportStarted(Swift_Events_TransportChangeEvent $evt);
|
||||
|
||||
/**
|
||||
* Invoked just before a Transport is stopped.
|
||||
*
|
||||
* @param Swift_Events_TransportChangeEvent $evt
|
||||
*/
|
||||
public function beforeTransportStopped(Swift_Events_TransportChangeEvent $evt);
|
||||
|
||||
/**
|
||||
* Invoked immediately after the Transport is stopped.
|
||||
*
|
||||
* @param Swift_Events_TransportChangeEvent $evt
|
||||
*/
|
||||
public function transportStopped(Swift_Events_TransportChangeEvent $evt);
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generated when a TransportException is thrown from the Transport system.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Events_TransportExceptionEvent extends Swift_Events_EventObject
|
||||
{
|
||||
/**
|
||||
* The Exception thrown.
|
||||
*
|
||||
* @var Swift_TransportException
|
||||
*/
|
||||
private $_exception;
|
||||
|
||||
/**
|
||||
* Create a new TransportExceptionEvent for $transport.
|
||||
*
|
||||
* @param Swift_Transport $transport
|
||||
* @param Swift_TransportException $ex
|
||||
*/
|
||||
public function __construct(Swift_Transport $transport, Swift_TransportException $ex)
|
||||
{
|
||||
parent::__construct($transport);
|
||||
$this->_exception = $ex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TransportException thrown.
|
||||
*
|
||||
* @return Swift_TransportException
|
||||
*/
|
||||
public function getException()
|
||||
{
|
||||
return $this->_exception;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Listens for Exceptions thrown from within the Transport system.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Events
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Events_TransportExceptionListener extends Swift_Events_EventListener
|
||||
{
|
||||
/**
|
||||
* Invoked as a TransportException is thrown in the Transport system.
|
||||
*
|
||||
* @param Swift_Events_TransportExceptionEvent $evt
|
||||
*/
|
||||
public function exceptionThrown(Swift_Events_TransportExceptionEvent $evt);
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains a list of redundant Transports so when one fails, the next is used.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Transport
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_FailoverTransport extends Swift_Transport_FailoverTransport
|
||||
{
|
||||
/**
|
||||
* Creates a new FailoverTransport with $transports.
|
||||
*
|
||||
* @param Swift_Transport[] $transports
|
||||
*/
|
||||
public function __construct($transports = array())
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Transport_FailoverTransport::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('transport.failover')
|
||||
);
|
||||
|
||||
$this->setTransports($transports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FailoverTransport instance.
|
||||
*
|
||||
* @param Swift_Transport[] $transports
|
||||
*
|
||||
* @return Swift_FailoverTransport
|
||||
*/
|
||||
public static function newInstance($transports = array())
|
||||
{
|
||||
return new self($transports);
|
||||
}
|
||||
}
|
||||
209
public/include/lib/swiftmailer/classes/Swift/FileSpool.php
Normal file
209
public/include/lib/swiftmailer/classes/Swift/FileSpool.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2009 Fabien Potencier <fabien.potencier@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Stores Messages on the filesystem.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Fabien Potencier
|
||||
* @author Xavier De Cock <xdecock@gmail.com>
|
||||
*/
|
||||
class Swift_FileSpool extends Swift_ConfigurableSpool
|
||||
{
|
||||
/** The spool directory */
|
||||
private $_path;
|
||||
|
||||
/**
|
||||
* File WriteRetry Limit
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_retryLimit=10;
|
||||
|
||||
/**
|
||||
* Create a new FileSpool.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function __construct($path)
|
||||
{
|
||||
$this->_path = $path;
|
||||
|
||||
if (!file_exists($this->_path)) {
|
||||
if (!mkdir($this->_path, 0777, true)) {
|
||||
throw new Swift_IoException('Unable to create Path ['.$this->_path.']');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if this Spool mechanism has started.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isStarted()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts this Spool mechanism.
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops this Spool mechanism.
|
||||
*/
|
||||
public function stop()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to manage the enqueuing retry limit.
|
||||
*
|
||||
* Default, is ten and allows over 64^20 different fileNames
|
||||
*
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function setRetryLimit($limit)
|
||||
{
|
||||
$this->_retryLimit=$limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queues a message.
|
||||
*
|
||||
* @param Swift_Mime_Message $message The message to store
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function queueMessage(Swift_Mime_Message $message)
|
||||
{
|
||||
$ser = serialize($message);
|
||||
$fileName = $this->_path . '/' . $this->getRandomString(10);
|
||||
for ($i = 0; $i < $this->_retryLimit; ++$i) {
|
||||
/* We try an exclusive creation of the file. This is an atomic operation, it avoid locking mechanism */
|
||||
$fp = @fopen($fileName . '.message', 'x');
|
||||
if (false !== $fp) {
|
||||
if (false === fwrite($fp, $ser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fclose($fp);
|
||||
} else {
|
||||
/* The file already exists, we try a longer fileName */
|
||||
$fileName .= $this->getRandomString(1);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Swift_IoException('Unable to create a file for enqueuing Message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a recovery if for any reason a process is sending for too long.
|
||||
*
|
||||
* @param integer $timeout in second Defaults is for very slow smtp responses
|
||||
*/
|
||||
public function recover($timeout = 900)
|
||||
{
|
||||
foreach (new DirectoryIterator($this->_path) as $file) {
|
||||
$file = $file->getRealPath();
|
||||
|
||||
if (substr($file, - 16) == '.message.sending') {
|
||||
$lockedtime = filectime($file);
|
||||
if ((time() - $lockedtime) > $timeout) {
|
||||
rename($file, substr($file, 0, - 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages using the given transport instance.
|
||||
*
|
||||
* @param Swift_Transport $transport A transport instance
|
||||
* @param string[] $failedRecipients An array of failures by-reference
|
||||
*
|
||||
* @return integer The number of sent e-mail's
|
||||
*/
|
||||
public function flushQueue(Swift_Transport $transport, &$failedRecipients = null)
|
||||
{
|
||||
$directoryIterator = new DirectoryIterator($this->_path);
|
||||
|
||||
/* Start the transport only if there are queued files to send */
|
||||
if (!$transport->isStarted()) {
|
||||
foreach ($directoryIterator as $file) {
|
||||
if (substr($file->getRealPath(), -8) == '.message') {
|
||||
$transport->start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$failedRecipients = (array) $failedRecipients;
|
||||
$count = 0;
|
||||
$time = time();
|
||||
foreach ($directoryIterator as $file) {
|
||||
$file = $file->getRealPath();
|
||||
|
||||
if (substr($file, -8) != '.message') {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We try a rename, it's an atomic operation, and avoid locking the file */
|
||||
if (rename($file, $file.'.sending')) {
|
||||
$message = unserialize(file_get_contents($file.'.sending'));
|
||||
|
||||
$count += $transport->send($message, $failedRecipients);
|
||||
|
||||
unlink($file.'.sending');
|
||||
} else {
|
||||
/* This message has just been catched by another process */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->getMessageLimit() && $count >= $this->getMessageLimit()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->getTimeLimit() && (time() - $time) >= $this->getTimeLimit()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random string needed to generate a fileName for the queue.
|
||||
*
|
||||
* @param integer $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getRandomString($count)
|
||||
{
|
||||
// This string MUST stay FS safe, avoid special chars
|
||||
$base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.";
|
||||
$ret = '';
|
||||
$strlen = strlen($base);
|
||||
for ($i = 0; $i < $count; ++$i) {
|
||||
$ret .= $base[((int) rand(0, $strlen - 1))];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
26
public/include/lib/swiftmailer/classes/Swift/FileStream.php
Normal file
26
public/include/lib/swiftmailer/classes/Swift/FileStream.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An OutputByteStream which specifically reads from a file.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage ByteStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_FileStream extends Swift_OutputByteStream
|
||||
{
|
||||
/**
|
||||
* Get the complete path to the file.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath();
|
||||
}
|
||||
33
public/include/lib/swiftmailer/classes/Swift/Filterable.php
Normal file
33
public/include/lib/swiftmailer/classes/Swift/Filterable.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows StreamFilters to operate on a stream.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Filterable
|
||||
{
|
||||
/**
|
||||
* Add a new StreamFilter, referenced by $key.
|
||||
*
|
||||
* @param Swift_StreamFilter $filter
|
||||
* @param string $key
|
||||
*/
|
||||
public function addFilter(Swift_StreamFilter $filter, $key);
|
||||
|
||||
/**
|
||||
* Remove an existing filter using $key.
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
public function removeFilter($key);
|
||||
}
|
||||
63
public/include/lib/swiftmailer/classes/Swift/Image.php
Normal file
63
public/include/lib/swiftmailer/classes/Swift/Image.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An image, embedded in a multipart message.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Image extends Swift_EmbeddedFile
|
||||
{
|
||||
/**
|
||||
* Create a new EmbeddedFile.
|
||||
*
|
||||
* Details may be optionally provided to the constructor.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $data
|
||||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*/
|
||||
public function __construct($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
parent::__construct($data, $filename, $contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Image.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $data
|
||||
* @param string $filename
|
||||
* @param string $contentType
|
||||
*
|
||||
* @return Swift_Image
|
||||
*/
|
||||
public static function newInstance($data = null, $filename = null, $contentType = null)
|
||||
{
|
||||
return new self($data, $filename, $contentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Image from a filesystem path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Swift_Image
|
||||
*/
|
||||
public static function fromPath($path)
|
||||
{
|
||||
$image = self::newInstance()->setFile(
|
||||
new Swift_ByteStream_FileByteStream($path)
|
||||
);
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An abstract means of writing data.
|
||||
*
|
||||
* Classes implementing this interface may use a subsystem which requires less
|
||||
* memory than working with large strings of data.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage ByteStream
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_InputByteStream
|
||||
{
|
||||
/**
|
||||
* Writes $bytes to the end of the stream.
|
||||
*
|
||||
* Writing may not happen immediately if the stream chooses to buffer. If
|
||||
* you want to write these bytes with immediate effect, call {@link commit()}
|
||||
* after calling write().
|
||||
*
|
||||
* This method returns the sequence ID of the write (i.e. 1 for first, 2 for
|
||||
* second, etc etc).
|
||||
*
|
||||
* @param string $bytes
|
||||
*
|
||||
* @return integer
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function write($bytes);
|
||||
|
||||
/**
|
||||
* For any bytes that are currently buffered inside the stream, force them
|
||||
* off the buffer.
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function commit();
|
||||
|
||||
/**
|
||||
* Attach $is to this stream.
|
||||
*
|
||||
* The stream acts as an observer, receiving all data that is written.
|
||||
* All {@link write()} and {@link flushBuffers()} operations will be mirrored.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function bind(Swift_InputByteStream $is);
|
||||
|
||||
/**
|
||||
* Remove an already bound stream.
|
||||
*
|
||||
* If $is is not bound, no errors will be raised.
|
||||
* If the stream currently has any buffered data it will be written to $is
|
||||
* before unbinding occurs.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function unbind(Swift_InputByteStream $is);
|
||||
|
||||
/**
|
||||
* Flush the contents of the stream (empty it) and set the internal pointer
|
||||
* to the beginning.
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function flushBuffers();
|
||||
}
|
||||
28
public/include/lib/swiftmailer/classes/Swift/IoException.php
Normal file
28
public/include/lib/swiftmailer/classes/Swift/IoException.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* I/O Exception class.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_IoException extends Swift_SwiftException
|
||||
{
|
||||
/**
|
||||
* Create a new IoException with $message.
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function __construct($message)
|
||||
{
|
||||
parent::__construct($message);
|
||||
}
|
||||
}
|
||||
107
public/include/lib/swiftmailer/classes/Swift/KeyCache.php
Normal file
107
public/include/lib/swiftmailer/classes/Swift/KeyCache.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a mechanism for storing data using two keys.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage KeyCache
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_KeyCache
|
||||
{
|
||||
/** Mode for replacing existing cached data */
|
||||
const MODE_WRITE = 1;
|
||||
|
||||
/** Mode for appending data to the end of existing cached data */
|
||||
const MODE_APPEND = 2;
|
||||
|
||||
/**
|
||||
* Set a string into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param string $string
|
||||
* @param integer $mode
|
||||
*/
|
||||
public function setString($nsKey, $itemKey, $string, $mode);
|
||||
|
||||
/**
|
||||
* Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_OutputByteStream $os
|
||||
* @param integer $mode
|
||||
*/
|
||||
public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode);
|
||||
|
||||
/**
|
||||
* Provides a ByteStream which when written to, writes data to $itemKey.
|
||||
*
|
||||
* NOTE: The stream will always write in append mode.
|
||||
* If the optional third parameter is passed all writes will go through $is.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $is optional input stream
|
||||
*
|
||||
* @return Swift_InputByteStream
|
||||
*/
|
||||
public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $is = null);
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a string.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($nsKey, $itemKey);
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a ByteStream.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $is stream to write the data to
|
||||
*/
|
||||
public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is);
|
||||
|
||||
/**
|
||||
* Check if the given $itemKey exists in the namespace $nsKey.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasKey($nsKey, $itemKey);
|
||||
|
||||
/**
|
||||
* Clear data for $itemKey in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*/
|
||||
public function clearKey($nsKey, $itemKey);
|
||||
|
||||
/**
|
||||
* Clear all data in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
public function clearAll($nsKey);
|
||||
}
|
||||
@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A basic KeyCache backed by an array.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage KeyCache
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache
|
||||
{
|
||||
/**
|
||||
* Cache contents.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_contents = array();
|
||||
|
||||
/**
|
||||
* An InputStream for cloning.
|
||||
*
|
||||
* @var Swift_KeyCache_KeyCacheInputStream
|
||||
*/
|
||||
private $_stream;
|
||||
|
||||
/**
|
||||
* Create a new ArrayKeyCache with the given $stream for cloning to make
|
||||
* InputByteStreams.
|
||||
*
|
||||
* @param Swift_KeyCache_KeyCacheInputStream $stream
|
||||
*/
|
||||
public function __construct(Swift_KeyCache_KeyCacheInputStream $stream)
|
||||
{
|
||||
$this->_stream = $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a string into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param string $string
|
||||
* @param integer $mode
|
||||
*/
|
||||
public function setString($nsKey, $itemKey, $string, $mode)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
switch ($mode) {
|
||||
case self::MODE_WRITE:
|
||||
$this->_contents[$nsKey][$itemKey] = $string;
|
||||
break;
|
||||
case self::MODE_APPEND:
|
||||
if (!$this->hasKey($nsKey, $itemKey)) {
|
||||
$this->_contents[$nsKey][$itemKey] = '';
|
||||
}
|
||||
$this->_contents[$nsKey][$itemKey] .= $string;
|
||||
break;
|
||||
default:
|
||||
throw new Swift_SwiftException(
|
||||
'Invalid mode [' . $mode . '] used to set nsKey='.
|
||||
$nsKey . ', itemKey=' . $itemKey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_OutputByteStream $os
|
||||
* @param integer $mode
|
||||
*/
|
||||
public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
switch ($mode) {
|
||||
case self::MODE_WRITE:
|
||||
$this->clearKey($nsKey, $itemKey);
|
||||
case self::MODE_APPEND:
|
||||
if (!$this->hasKey($nsKey, $itemKey)) {
|
||||
$this->_contents[$nsKey][$itemKey] = '';
|
||||
}
|
||||
while (false !== $bytes = $os->read(8192)) {
|
||||
$this->_contents[$nsKey][$itemKey] .= $bytes;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Swift_SwiftException(
|
||||
'Invalid mode [' . $mode . '] used to set nsKey='.
|
||||
$nsKey . ', itemKey=' . $itemKey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a ByteStream which when written to, writes data to $itemKey.
|
||||
*
|
||||
* NOTE: The stream will always write in append mode.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $writeThrough
|
||||
*
|
||||
* @return Swift_InputByteStream
|
||||
*/
|
||||
public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null)
|
||||
{
|
||||
$is = clone $this->_stream;
|
||||
$is->setKeyCache($this);
|
||||
$is->setNsKey($nsKey);
|
||||
$is->setItemKey($itemKey);
|
||||
if (isset($writeThrough)) {
|
||||
$is->setWriteThroughStream($writeThrough);
|
||||
}
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a string.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($nsKey, $itemKey)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
if ($this->hasKey($nsKey, $itemKey)) {
|
||||
return $this->_contents[$nsKey][$itemKey];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a ByteStream.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $is to write the data to
|
||||
*/
|
||||
public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
$is->write($this->getString($nsKey, $itemKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given $itemKey exists in the namespace $nsKey.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasKey($nsKey, $itemKey)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
|
||||
return array_key_exists($itemKey, $this->_contents[$nsKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear data for $itemKey in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*/
|
||||
public function clearKey($nsKey, $itemKey)
|
||||
{
|
||||
unset($this->_contents[$nsKey][$itemKey]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
public function clearAll($nsKey)
|
||||
{
|
||||
unset($this->_contents[$nsKey]);
|
||||
}
|
||||
|
||||
// -- Private methods
|
||||
|
||||
/**
|
||||
* Initialize the namespace of $nsKey if needed.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
private function _prepareCache($nsKey)
|
||||
{
|
||||
if (!array_key_exists($nsKey, $this->_contents)) {
|
||||
$this->_contents[$nsKey] = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,328 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A KeyCache which streams to and from disk.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage KeyCache
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_KeyCache_DiskKeyCache implements Swift_KeyCache
|
||||
{
|
||||
/** Signal to place pointer at start of file */
|
||||
const POSITION_START = 0;
|
||||
|
||||
/** Signal to place pointer at end of file */
|
||||
const POSITION_END = 1;
|
||||
|
||||
/** Signal to leave pointer in whatever position it currently is */
|
||||
const POSITION_CURRENT = 2;
|
||||
|
||||
/**
|
||||
* An InputStream for cloning.
|
||||
*
|
||||
* @var Swift_KeyCache_KeyCacheInputStream
|
||||
*/
|
||||
private $_stream;
|
||||
|
||||
/**
|
||||
* A path to write to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_path;
|
||||
|
||||
/**
|
||||
* Stored keys.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_keys = array();
|
||||
|
||||
/**
|
||||
* Will be true if magic_quotes_runtime is turned on.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_quotes = false;
|
||||
|
||||
/**
|
||||
* Create a new DiskKeyCache with the given $stream for cloning to make
|
||||
* InputByteStreams, and the given $path to save to.
|
||||
*
|
||||
* @param Swift_KeyCache_KeyCacheInputStream $stream
|
||||
* @param string $path to save to
|
||||
*/
|
||||
public function __construct(Swift_KeyCache_KeyCacheInputStream $stream, $path)
|
||||
{
|
||||
$this->_stream = $stream;
|
||||
$this->_path = $path;
|
||||
|
||||
if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) {
|
||||
$this->_quotes = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a string into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param string $string
|
||||
* @param integer $mode
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function setString($nsKey, $itemKey, $string, $mode)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
switch ($mode) {
|
||||
case self::MODE_WRITE:
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
|
||||
break;
|
||||
case self::MODE_APPEND:
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
|
||||
break;
|
||||
default:
|
||||
throw new Swift_SwiftException(
|
||||
'Invalid mode [' . $mode . '] used to set nsKey='.
|
||||
$nsKey . ', itemKey=' . $itemKey
|
||||
);
|
||||
break;
|
||||
}
|
||||
fwrite($fp, $string);
|
||||
$this->_freeHandle($nsKey, $itemKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_OutputByteStream $os
|
||||
* @param integer $mode
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
switch ($mode) {
|
||||
case self::MODE_WRITE:
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
|
||||
break;
|
||||
case self::MODE_APPEND:
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_END);
|
||||
break;
|
||||
default:
|
||||
throw new Swift_SwiftException(
|
||||
'Invalid mode [' . $mode . '] used to set nsKey='.
|
||||
$nsKey . ', itemKey=' . $itemKey
|
||||
);
|
||||
break;
|
||||
}
|
||||
while (false !== $bytes = $os->read(8192)) {
|
||||
fwrite($fp, $bytes);
|
||||
}
|
||||
$this->_freeHandle($nsKey, $itemKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a ByteStream which when written to, writes data to $itemKey.
|
||||
*
|
||||
* NOTE: The stream will always write in append mode.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $writeThrough
|
||||
*
|
||||
* @return Swift_InputByteStream
|
||||
*/
|
||||
public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null)
|
||||
{
|
||||
$is = clone $this->_stream;
|
||||
$is->setKeyCache($this);
|
||||
$is->setNsKey($nsKey);
|
||||
$is->setItemKey($itemKey);
|
||||
if (isset($writeThrough)) {
|
||||
$is->setWriteThroughStream($writeThrough);
|
||||
}
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a string.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Swift_IoException
|
||||
*/
|
||||
public function getString($nsKey, $itemKey)
|
||||
{
|
||||
$this->_prepareCache($nsKey);
|
||||
if ($this->hasKey($nsKey, $itemKey)) {
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
|
||||
if ($this->_quotes) {
|
||||
ini_set('magic_quotes_runtime', 0);
|
||||
}
|
||||
$str = '';
|
||||
while (!feof($fp) && false !== $bytes = fread($fp, 8192)) {
|
||||
$str .= $bytes;
|
||||
}
|
||||
if ($this->_quotes) {
|
||||
ini_set('magic_quotes_runtime', 1);
|
||||
}
|
||||
$this->_freeHandle($nsKey, $itemKey);
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a ByteStream.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $is to write the data to
|
||||
*/
|
||||
public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
|
||||
{
|
||||
if ($this->hasKey($nsKey, $itemKey)) {
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_START);
|
||||
if ($this->_quotes) {
|
||||
ini_set('magic_quotes_runtime', 0);
|
||||
}
|
||||
while (!feof($fp) && false !== $bytes = fread($fp, 8192)) {
|
||||
$is->write($bytes);
|
||||
}
|
||||
if ($this->_quotes) {
|
||||
ini_set('magic_quotes_runtime', 1);
|
||||
}
|
||||
$this->_freeHandle($nsKey, $itemKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given $itemKey exists in the namespace $nsKey.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasKey($nsKey, $itemKey)
|
||||
{
|
||||
return is_file($this->_path . '/' . $nsKey . '/' . $itemKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear data for $itemKey in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*/
|
||||
public function clearKey($nsKey, $itemKey)
|
||||
{
|
||||
if ($this->hasKey($nsKey, $itemKey)) {
|
||||
$this->_freeHandle($nsKey, $itemKey);
|
||||
unlink($this->_path . '/' . $nsKey . '/' . $itemKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
public function clearAll($nsKey)
|
||||
{
|
||||
if (array_key_exists($nsKey, $this->_keys)) {
|
||||
foreach ($this->_keys[$nsKey] as $itemKey=>$null) {
|
||||
$this->clearKey($nsKey, $itemKey);
|
||||
}
|
||||
if (is_dir($this->_path . '/' . $nsKey)) {
|
||||
rmdir($this->_path . '/' . $nsKey);
|
||||
}
|
||||
unset($this->_keys[$nsKey]);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Private methods
|
||||
|
||||
/**
|
||||
* Initialize the namespace of $nsKey if needed.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
private function _prepareCache($nsKey)
|
||||
{
|
||||
$cacheDir = $this->_path . '/' . $nsKey;
|
||||
if (!is_dir($cacheDir)) {
|
||||
if (!mkdir($cacheDir)) {
|
||||
throw new Swift_IoException('Failed to create cache directory ' . $cacheDir);
|
||||
}
|
||||
$this->_keys[$nsKey] = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a file handle on the cache item.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param integer $position
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private function _getHandle($nsKey, $itemKey, $position)
|
||||
{
|
||||
if (!isset($this->_keys[$nsKey][$itemKey])) {
|
||||
$openMode = $this->hasKey($nsKey, $itemKey)
|
||||
? 'r+b'
|
||||
: 'w+b'
|
||||
;
|
||||
$fp = fopen($this->_path . '/' . $nsKey . '/' . $itemKey, $openMode);
|
||||
$this->_keys[$nsKey][$itemKey] = $fp;
|
||||
}
|
||||
if (self::POSITION_START == $position) {
|
||||
fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_SET);
|
||||
} elseif (self::POSITION_END == $position) {
|
||||
fseek($this->_keys[$nsKey][$itemKey], 0, SEEK_END);
|
||||
}
|
||||
|
||||
return $this->_keys[$nsKey][$itemKey];
|
||||
}
|
||||
|
||||
private function _freeHandle($nsKey, $itemKey)
|
||||
{
|
||||
$fp = $this->_getHandle($nsKey, $itemKey, self::POSITION_CURRENT);
|
||||
fclose($fp);
|
||||
$this->_keys[$nsKey][$itemKey] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->_keys as $nsKey=>$null) {
|
||||
$this->clearAll($nsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes data to a KeyCache using a stream.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage KeyCache
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_KeyCache_KeyCacheInputStream extends Swift_InputByteStream
|
||||
{
|
||||
/**
|
||||
* Set the KeyCache to wrap.
|
||||
*
|
||||
* @param Swift_KeyCache $keyCache
|
||||
*/
|
||||
public function setKeyCache(Swift_KeyCache $keyCache);
|
||||
|
||||
/**
|
||||
* Set the nsKey which will be written to.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
public function setNsKey($nsKey);
|
||||
|
||||
/**
|
||||
* Set the itemKey which will be written to.
|
||||
*
|
||||
* @param string $itemKey
|
||||
*/
|
||||
public function setItemKey($itemKey);
|
||||
|
||||
/**
|
||||
* Specify a stream to write through for each write().
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function setWriteThroughStream(Swift_InputByteStream $is);
|
||||
|
||||
/**
|
||||
* Any implementation should be cloneable, allowing the clone to access a
|
||||
* separate $nsKey and $itemKey.
|
||||
*/
|
||||
public function __clone();
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A null KeyCache that does not cache at all.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage KeyCache
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_KeyCache_NullKeyCache implements Swift_KeyCache
|
||||
{
|
||||
/**
|
||||
* Set a string into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param string $string
|
||||
* @param integer $mode
|
||||
*/
|
||||
public function setString($nsKey, $itemKey, $string, $mode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
|
||||
*
|
||||
* @see MODE_WRITE, MODE_APPEND
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_OutputByteStream $os
|
||||
* @param integer $mode
|
||||
*/
|
||||
public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os, $mode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a ByteStream which when written to, writes data to $itemKey.
|
||||
*
|
||||
* NOTE: The stream will always write in append mode.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $writeThrough
|
||||
*
|
||||
* @return Swift_InputByteStream
|
||||
*/
|
||||
public function getInputByteStream($nsKey, $itemKey, Swift_InputByteStream $writeThrough = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a string.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getString($nsKey, $itemKey)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data back out of the cache as a ByteStream.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
* @param Swift_InputByteStream $is to write the data to
|
||||
*/
|
||||
public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given $itemKey exists in the namespace $nsKey.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasKey($nsKey, $itemKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear data for $itemKey in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
* @param string $itemKey
|
||||
*/
|
||||
public function clearKey($nsKey, $itemKey)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data in the namespace $nsKey if it exists.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
public function clearAll($nsKey)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Writes data to a KeyCache using a stream.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage KeyCache
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_KeyCache_SimpleKeyCacheInputStream implements Swift_KeyCache_KeyCacheInputStream
|
||||
{
|
||||
/** The KeyCache being written to */
|
||||
private $_keyCache;
|
||||
|
||||
/** The nsKey of the KeyCache being written to */
|
||||
private $_nsKey;
|
||||
|
||||
/** The itemKey of the KeyCache being written to */
|
||||
private $_itemKey;
|
||||
|
||||
/** A stream to write through on each write() */
|
||||
private $_writeThrough = null;
|
||||
|
||||
/**
|
||||
* Set the KeyCache to wrap.
|
||||
*
|
||||
* @param Swift_KeyCache $keyCache
|
||||
*/
|
||||
public function setKeyCache(Swift_KeyCache $keyCache)
|
||||
{
|
||||
$this->_keyCache = $keyCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a stream to write through for each write().
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function setWriteThroughStream(Swift_InputByteStream $is)
|
||||
{
|
||||
$this->_writeThrough = $is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes $bytes to the end of the stream.
|
||||
*
|
||||
* @param string $bytes
|
||||
* @param Swift_InputByteStream $is optional
|
||||
*/
|
||||
public function write($bytes, Swift_InputByteStream $is = null)
|
||||
{
|
||||
$this->_keyCache->setString(
|
||||
$this->_nsKey, $this->_itemKey, $bytes, Swift_KeyCache::MODE_APPEND
|
||||
);
|
||||
if (isset($is)) {
|
||||
$is->write($bytes);
|
||||
}
|
||||
if (isset($this->_writeThrough)) {
|
||||
$this->_writeThrough->write($bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function bind(Swift_InputByteStream $is)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used.
|
||||
*/
|
||||
public function unbind(Swift_InputByteStream $is)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the contents of the stream (empty it) and set the internal pointer
|
||||
* to the beginning.
|
||||
*/
|
||||
public function flushBuffers()
|
||||
{
|
||||
$this->_keyCache->clearKey($this->_nsKey, $this->_itemKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nsKey which will be written to.
|
||||
*
|
||||
* @param string $nsKey
|
||||
*/
|
||||
public function setNsKey($nsKey)
|
||||
{
|
||||
$this->_nsKey = $nsKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the itemKey which will be written to.
|
||||
*
|
||||
* @param string $itemKey
|
||||
*/
|
||||
public function setItemKey($itemKey)
|
||||
{
|
||||
$this->_itemKey = $itemKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any implementation should be cloneable, allowing the clone to access a
|
||||
* separate $nsKey and $itemKey.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->_writeThrough = null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Redundantly and rotationally uses several Transport implementations when sending.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Transport
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_LoadBalancedTransport extends Swift_Transport_LoadBalancedTransport
|
||||
{
|
||||
/**
|
||||
* Creates a new LoadBalancedTransport with $transports.
|
||||
*
|
||||
* @param array $transports
|
||||
*/
|
||||
public function __construct($transports = array())
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Transport_LoadBalancedTransport::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('transport.loadbalanced')
|
||||
);
|
||||
|
||||
$this->setTransports($transports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new LoadBalancedTransport instance.
|
||||
*
|
||||
* @param array $transports
|
||||
*
|
||||
* @return Swift_LoadBalancedTransport
|
||||
*/
|
||||
public static function newInstance($transports = array())
|
||||
{
|
||||
return new self($transports);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sends Messages using the mail() function.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Transport
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_MailTransport extends Swift_Transport_MailTransport
|
||||
{
|
||||
/**
|
||||
* Create a new MailTransport, optionally specifying $extraParams.
|
||||
*
|
||||
* @param string $extraParams
|
||||
*/
|
||||
public function __construct($extraParams = '-f%s')
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Transport_MailTransport::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('transport.mail')
|
||||
);
|
||||
|
||||
$this->setExtraParams($extraParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MailTransport instance.
|
||||
*
|
||||
* @param string $extraParams To be passed to mail()
|
||||
*
|
||||
* @return Swift_MailTransport
|
||||
*/
|
||||
public static function newInstance($extraParams = '-f%s')
|
||||
{
|
||||
return new self($extraParams);
|
||||
}
|
||||
}
|
||||
115
public/include/lib/swiftmailer/classes/Swift/Mailer.php
Normal file
115
public/include/lib/swiftmailer/classes/Swift/Mailer.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Swift Mailer class.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Mailer
|
||||
{
|
||||
/** The Transport used to send messages */
|
||||
private $_transport;
|
||||
|
||||
/**
|
||||
* Create a new Mailer using $transport for delivery.
|
||||
*
|
||||
* @param Swift_Transport $transport
|
||||
*/
|
||||
public function __construct(Swift_Transport $transport)
|
||||
{
|
||||
$this->_transport = $transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Mailer instance.
|
||||
*
|
||||
* @param Swift_Transport $transport
|
||||
*
|
||||
* @return Swift_Mailer
|
||||
*/
|
||||
public static function newInstance(Swift_Transport $transport)
|
||||
{
|
||||
return new self($transport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new class instance of one of the message services.
|
||||
*
|
||||
* For example 'mimepart' would create a 'message.mimepart' instance
|
||||
*
|
||||
* @param string $service
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function createMessage($service = 'message')
|
||||
{
|
||||
return Swift_DependencyContainer::getInstance()
|
||||
->lookup('message.'.$service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the given Message like it would be sent in a mail client.
|
||||
*
|
||||
* All recipients (with the exception of Bcc) will be able to see the other
|
||||
* recipients this message was sent to.
|
||||
*
|
||||
* Recipient/sender data will be retrieved from the Message object.
|
||||
*
|
||||
* The return value is the number of recipients who were accepted for
|
||||
* delivery.
|
||||
*
|
||||
* @param Swift_Mime_Message $message
|
||||
* @param array $failedRecipients An array of failures by-reference
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function send(Swift_Mime_Message $message, &$failedRecipients = null)
|
||||
{
|
||||
$failedRecipients = (array) $failedRecipients;
|
||||
|
||||
if (!$this->_transport->isStarted()) {
|
||||
$this->_transport->start();
|
||||
}
|
||||
|
||||
$sent = 0;
|
||||
|
||||
try {
|
||||
$sent = $this->_transport->send($message, $failedRecipients);
|
||||
} catch (Swift_RfcComplianceException $e) {
|
||||
foreach ($message->getTo() as $address => $name) {
|
||||
$failedRecipients[] = $address;
|
||||
}
|
||||
}
|
||||
|
||||
return $sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a plugin using a known unique key (e.g. myPlugin).
|
||||
*
|
||||
* @param Swift_Events_EventListener $plugin
|
||||
*/
|
||||
public function registerPlugin(Swift_Events_EventListener $plugin)
|
||||
{
|
||||
$this->_transport->registerPlugin($plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Transport used to send messages.
|
||||
*
|
||||
* @return Swift_Transport
|
||||
*/
|
||||
public function getTransport()
|
||||
{
|
||||
return $this->_transport;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wraps a standard PHP array in an iterator.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mailer
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Mailer_ArrayRecipientIterator implements Swift_Mailer_RecipientIterator
|
||||
{
|
||||
/**
|
||||
* The list of recipients.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_recipients = array();
|
||||
|
||||
/**
|
||||
* Create a new ArrayRecipientIterator from $recipients.
|
||||
*
|
||||
* @param array $recipients
|
||||
*/
|
||||
public function __construct(array $recipients)
|
||||
{
|
||||
$this->_recipients = $recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true only if there are more recipients to send to.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasNext()
|
||||
{
|
||||
return !empty($this->_recipients);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array where the keys are the addresses of recipients and the
|
||||
* values are the names. e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function nextRecipient()
|
||||
{
|
||||
return array_splice($this->_recipients, 0, 1);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides an abstract way of specifying recipients for batch sending.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mailer
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Mailer_RecipientIterator
|
||||
{
|
||||
/**
|
||||
* Returns true only if there are more recipients to send to.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasNext();
|
||||
|
||||
/**
|
||||
* Returns an array where the keys are the addresses of recipients and the
|
||||
* values are the names. e.g. ('foo@bar' => 'Foo') or ('foo@bar' => NULL)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function nextRecipient();
|
||||
}
|
||||
84
public/include/lib/swiftmailer/classes/Swift/MemorySpool.php
Normal file
84
public/include/lib/swiftmailer/classes/Swift/MemorySpool.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2011 Fabien Potencier <fabien.potencier@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Stores Messages in memory.
|
||||
*
|
||||
* @package Swift
|
||||
* @author Fabien Potencier
|
||||
*/
|
||||
class Swift_MemorySpool implements Swift_Spool
|
||||
{
|
||||
protected $messages = array();
|
||||
|
||||
/**
|
||||
* Tests if this Transport mechanism has started.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isStarted()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts this Transport mechanism.
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops this Transport mechanism.
|
||||
*/
|
||||
public function stop()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a message in the queue.
|
||||
*
|
||||
* @param Swift_Mime_Message $message The message to store
|
||||
*
|
||||
* @return boolean Whether the operation has succeeded
|
||||
*/
|
||||
public function queueMessage(Swift_Mime_Message $message)
|
||||
{
|
||||
$this->messages[] = $message;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages using the given transport instance.
|
||||
*
|
||||
* @param Swift_Transport $transport A transport instance
|
||||
* @param string[] $failedRecipients An array of failures by-reference
|
||||
*
|
||||
* @return integer The number of sent emails
|
||||
*/
|
||||
public function flushQueue(Swift_Transport $transport, &$failedRecipients = null)
|
||||
{
|
||||
if (!$this->messages) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$transport->isStarted()) {
|
||||
$transport->start();
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
while ($message = array_pop($this->messages)) {
|
||||
$count += $transport->send($message, $failedRecipients);
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
273
public/include/lib/swiftmailer/classes/Swift/Message.php
Normal file
273
public/include/lib/swiftmailer/classes/Swift/Message.php
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Message class for building emails.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Message extends Swift_Mime_SimpleMessage
|
||||
{
|
||||
/**
|
||||
* @var Swift_Signers_HeaderSigner[]
|
||||
*/
|
||||
private $headerSigners = array();
|
||||
|
||||
/**
|
||||
* @var Swift_Signers_BodySigner[]
|
||||
*/
|
||||
private $bodySigners = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $savedMessage = array();
|
||||
|
||||
/**
|
||||
* Create a new Message.
|
||||
*
|
||||
* Details may be optionally passed into the constructor.
|
||||
*
|
||||
* @param string $subject
|
||||
* @param string $body
|
||||
* @param string $contentType
|
||||
* @param string $charset
|
||||
*/
|
||||
public function __construct($subject = null, $body = null, $contentType = null, $charset = null)
|
||||
{
|
||||
call_user_func_array(
|
||||
array($this, 'Swift_Mime_SimpleMessage::__construct'),
|
||||
Swift_DependencyContainer::getInstance()
|
||||
->createDependenciesFor('mime.message')
|
||||
);
|
||||
|
||||
if (!isset($charset)) {
|
||||
$charset = Swift_DependencyContainer::getInstance()
|
||||
->lookup('properties.charset');
|
||||
}
|
||||
$this->setSubject($subject);
|
||||
$this->setBody($body);
|
||||
$this->setCharset($charset);
|
||||
if ($contentType) {
|
||||
$this->setContentType($contentType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Message.
|
||||
*
|
||||
* @param string $subject
|
||||
* @param string $body
|
||||
* @param string $contentType
|
||||
* @param string $charset
|
||||
*
|
||||
* @return Swift_Message
|
||||
*/
|
||||
public static function newInstance($subject = null, $body = null, $contentType = null, $charset = null)
|
||||
{
|
||||
return new self($subject, $body, $contentType, $charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a MimePart to this Message.
|
||||
*
|
||||
* @param string|Swift_OutputByteStream $body
|
||||
* @param string $contentType
|
||||
* @param string $charset
|
||||
*
|
||||
* @return Swift_Mime_SimpleMessage
|
||||
*/
|
||||
public function addPart($body, $contentType = null, $charset = null)
|
||||
{
|
||||
return $this->attach(Swift_MimePart::newInstance(
|
||||
$body, $contentType, $charset
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a new signature handler to the message.
|
||||
*
|
||||
* @param Swift_Signer $signer
|
||||
* @return Swift_Message
|
||||
*/
|
||||
public function attachSigner(Swift_Signer $signer)
|
||||
{
|
||||
if ($signer instanceof Swift_Signers_HeaderSigner) {
|
||||
$this->headerSigners[] = $signer;
|
||||
} elseif ($signer instanceof Swift_Signers_BodySigner) {
|
||||
$this->bodySigners[] = $signer;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a new signature handler to the message.
|
||||
*
|
||||
* @param Swift_Signer $signer
|
||||
* @return Swift_Message
|
||||
*/
|
||||
public function detachSigner(Swift_Signer $signer)
|
||||
{
|
||||
if ($signer instanceof Swift_Signers_HeaderSigner) {
|
||||
foreach ($this->headerSigners as $k => $headerSigner) {
|
||||
if ($headerSigner === $signer) {
|
||||
unset($this->headerSigners[$k]);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
} elseif ($signer instanceof Swift_Signers_BodySigner) {
|
||||
foreach ($this->bodySigners as $k => $bodySigner) {
|
||||
if ($bodySigner === $signer) {
|
||||
unset($this->bodySigners[$k]);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this message as a complete string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
if (empty($this->headerSigners) && empty($this->bodySigners)) {
|
||||
return parent::toString();
|
||||
}
|
||||
|
||||
$this->saveMessage();
|
||||
|
||||
$this->doSign();
|
||||
|
||||
$string = parent::toString();
|
||||
|
||||
$this->restoreMessage();
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write this message to a {@link Swift_InputByteStream}.
|
||||
*
|
||||
* @param Swift_InputByteStream $is
|
||||
*/
|
||||
public function toByteStream(Swift_InputByteStream $is)
|
||||
{
|
||||
if (empty($this->headerSigners) && empty($this->bodySigners)) {
|
||||
parent::toByteStream($is);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->saveMessage();
|
||||
|
||||
$this->doSign();
|
||||
|
||||
parent::toByteStream($is);
|
||||
|
||||
$this->restoreMessage();
|
||||
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
Swift_DependencyContainer::getInstance()->createDependenciesFor('mime.message');
|
||||
}
|
||||
|
||||
/* -- Protected Methods -- */
|
||||
|
||||
/**
|
||||
* loops through signers and apply the signatures
|
||||
*/
|
||||
protected function doSign()
|
||||
{
|
||||
foreach ($this->bodySigners as $signer) {
|
||||
$altered = $signer->getAlteredHeaders();
|
||||
$this->saveHeaders($altered);
|
||||
$signer->signMessage($this);
|
||||
}
|
||||
|
||||
foreach ($this->headerSigners as $signer) {
|
||||
$altered = $signer->getAlteredHeaders();
|
||||
$this->saveHeaders($altered);
|
||||
$signer->reset();
|
||||
|
||||
$signer->setHeaders($this->getHeaders());
|
||||
|
||||
$signer->startBody();
|
||||
$this->_bodyToByteStream($signer);
|
||||
$signer->endBody();
|
||||
|
||||
$signer->addSignature($this->getHeaders());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save the message before any signature is applied
|
||||
*/
|
||||
protected function saveMessage()
|
||||
{
|
||||
$this->savedMessage = array('headers'=> array());
|
||||
$this->savedMessage['body'] = $this->getBody();
|
||||
$this->savedMessage['children'] = $this->getChildren();
|
||||
if (count($this->savedMessage['children']) > 0 && $this->getBody() != '') {
|
||||
$this->setChildren(array_merge(array($this->_becomeMimePart()), $this->savedMessage['children']));
|
||||
$this->setBody('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* save the original headers
|
||||
* @param array $altered
|
||||
*/
|
||||
protected function saveHeaders(array $altered)
|
||||
{
|
||||
foreach ($altered as $head) {
|
||||
$lc = strtolower($head);
|
||||
|
||||
if (!isset($this->savedMessage['headers'][$lc])) {
|
||||
$this->savedMessage['headers'][$lc] = $this->getHeaders()->getAll($head);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove or restore altered headers
|
||||
*/
|
||||
protected function restoreHeaders()
|
||||
{
|
||||
foreach ($this->savedMessage['headers'] as $name => $savedValue) {
|
||||
$headers = $this->getHeaders()->getAll($name);
|
||||
|
||||
foreach ($headers as $key => $value) {
|
||||
if (!isset($savedValue[$key])) {
|
||||
$this->getHeaders()->remove($name, $key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore message body
|
||||
*/
|
||||
protected function restoreMessage()
|
||||
{
|
||||
$this->setBody($this->savedMessage['body']);
|
||||
$this->setChildren($this->savedMessage['children']);
|
||||
|
||||
$this->restoreHeaders();
|
||||
$this->savedMessage = array();
|
||||
}
|
||||
}
|
||||
155
public/include/lib/swiftmailer/classes/Swift/Mime/Attachment.php
Normal file
155
public/include/lib/swiftmailer/classes/Swift/Mime/Attachment.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An attachment, in a multipart message.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
class Swift_Mime_Attachment extends Swift_Mime_SimpleMimeEntity
|
||||
{
|
||||
/** Recognized MIME types */
|
||||
private $_mimeTypes = array();
|
||||
|
||||
/**
|
||||
* Create a new Attachment with $headers, $encoder and $cache.
|
||||
*
|
||||
* @param Swift_Mime_HeaderSet $headers
|
||||
* @param Swift_Mime_ContentEncoder $encoder
|
||||
* @param Swift_KeyCache $cache
|
||||
* @param Swift_Mime_Grammar $grammar
|
||||
* @param array $mimeTypes optional
|
||||
*/
|
||||
public function __construct(Swift_Mime_HeaderSet $headers, Swift_Mime_ContentEncoder $encoder, Swift_KeyCache $cache, Swift_Mime_Grammar $grammar, $mimeTypes = array())
|
||||
{
|
||||
parent::__construct($headers, $encoder, $cache, $grammar);
|
||||
$this->setDisposition('attachment');
|
||||
$this->setContentType('application/octet-stream');
|
||||
$this->_mimeTypes = $mimeTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nesting level used for this attachment.
|
||||
*
|
||||
* Always returns {@link LEVEL_MIXED}.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getNestingLevel()
|
||||
{
|
||||
return self::LEVEL_MIXED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Content-Disposition of this attachment.
|
||||
*
|
||||
* By default attachments have a disposition of "attachment".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDisposition()
|
||||
{
|
||||
return $this->_getHeaderFieldModel('Content-Disposition');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Content-Disposition of this attachment.
|
||||
*
|
||||
* @param string $disposition
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
*/
|
||||
public function setDisposition($disposition)
|
||||
{
|
||||
if (!$this->_setHeaderFieldModel('Content-Disposition', $disposition)) {
|
||||
$this->getHeaders()->addParameterizedHeader(
|
||||
'Content-Disposition', $disposition
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filename of this attachment when downloaded.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->_getHeaderParameter('Content-Disposition', 'filename');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filename of this attachment.
|
||||
*
|
||||
* @param string $filename
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->_setHeaderParameter('Content-Disposition', 'filename', $filename);
|
||||
$this->_setHeaderParameter('Content-Type', 'name', $filename);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file size of this attachment.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return $this->_getHeaderParameter('Content-Disposition', 'size');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file size of this attachment.
|
||||
*
|
||||
* @param integer $size
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
*/
|
||||
public function setSize($size)
|
||||
{
|
||||
$this->_setHeaderParameter('Content-Disposition', 'size', $size);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the file that this attachment is for.
|
||||
*
|
||||
* @param Swift_FileStream $file
|
||||
* @param string $contentType optional
|
||||
*
|
||||
* @return Swift_Mime_Attachment
|
||||
*/
|
||||
public function setFile(Swift_FileStream $file, $contentType = null)
|
||||
{
|
||||
$this->setFilename(basename($file->getPath()));
|
||||
$this->setBody($file, $contentType);
|
||||
if (!isset($contentType)) {
|
||||
$extension = strtolower(substr(
|
||||
$file->getPath(), strrpos($file->getPath(), '.') + 1
|
||||
));
|
||||
|
||||
if (array_key_exists($extension, $this->_mimeTypes)) {
|
||||
$this->setContentType($this->_mimeTypes[$extension]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Observes changes in an Mime entity's character set.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Mime_CharsetObserver
|
||||
{
|
||||
/**
|
||||
* Notify this observer that the entity's charset has changed.
|
||||
*
|
||||
* @param string $charset
|
||||
*/
|
||||
public function charsetChanged($charset);
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of SwiftMailer.
|
||||
* (c) 2004-2009 Chris Corbyn
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for all Transfer Encoding schemes.
|
||||
*
|
||||
* @package Swift
|
||||
* @subpackage Mime
|
||||
* @author Chris Corbyn
|
||||
*/
|
||||
interface Swift_Mime_ContentEncoder extends Swift_Encoder
|
||||
{
|
||||
/**
|
||||
* Encode $in to $out.
|
||||
*
|
||||
* @param Swift_OutputByteStream $os to read from
|
||||
* @param Swift_InputByteStream $is to write to
|
||||
* @param integer $firstLineOffset
|
||||
* @param integer $maxLineLength - 0 indicates the default length for this encoding
|
||||
*/
|
||||
public function encodeByteStream(Swift_OutputByteStream $os, Swift_InputByteStream $is, $firstLineOffset = 0, $maxLineLength = 0);
|
||||
|
||||
/**
|
||||
* Get the MIME name of this content encoding scheme.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user