function run() { // Make sure that the output is sent to the browser before // loading libraries and connecting to the db flush(); $aConf = $GLOBALS['_MAX']['CONF']; // Set longer time out, and ignore user abort if (!ini_get('safe_mode')) { @set_time_limit($aConf['maintenance']['timeLimitScripts']); @ignore_user_abort(true); } if (!defined('OA_VERSION')) { // If the code is executed inside delivery, the constants // need to be initialized require_once MAX_PATH . '/constants.php'; setupConstants(); } $oLock =& OA_DB_AdvisoryLock::factory(); if ($oLock->get(OA_DB_ADVISORYLOCK_MAINTENANCE)) { OA::debug('Running Automatic Maintenance Task', PEAR_LOG_INFO); OA_Preferences::loadAdminAccountPreferences(); require_once LIB_PATH . '/Maintenance.php'; $oMaint = new OX_Maintenance(); $oMaint->run(); $oLock->release(); OA::debug('Automatic Maintenance Task Completed', PEAR_LOG_INFO); } else { OA::debug('Automatic Maintenance Task not run: could not acquire lock', PEAR_LOG_INFO); } }
function OX_Maintenance() { $this->aConf = $GLOBALS['_MAX']['CONF']; OA_Preferences::loadAdminAccountPreferences(); $this->aPref = $GLOBALS['_MAX']['PREF']; // Get a connection to the datbase $this->oDbh =& OA_DB::singleton(); if (PEAR::isError($this->oDbh)) { // Unable to continue! MAX::raiseError($this->oDbh, null, PEAR_ERROR_DIE); } }
/** * This function recreates the data_summary_ad_hourly table rolls-up hourly stats to daily totals * The roll-up is done in accordance to the user's (currently) selected timezone * * @param PEAR_Date $oDate The date before which hourly stats should be rolled up */ function _rollUpHourlyStatsToDaily($oDate) { $sDate = $oDate->format('%Y-%m-%d 00:00:00'); $updated = OA::getNowUTC('Y-m-d h:i:s'); OA::debug("Beginning stats rollup for pre-{$sDate}", PEAR_LOG_INFO); // First create a temporary table with ad_id/offset pairs, this can then be joined in a (compled) INSERT INTO ... SELECT FROM statement $aTimezones = OX_Admin_Timezones::availableTimezones(false); $aAdminPreferences = OA_Preferences::loadAdminAccountPreferences(true); $aAdminTzOffset = $this->_getSqlOffsetFromString($aTimezones[$aAdminPreferences['timezone']]); // CREATE a timezone string => offset table (since the format we use in PHP is incompatible with the format used by MySQL) $this->oDbh->exec("DROP TABLE IF EXISTS {$this->prefix}tmp_tz_offset"); $this->oDbh->exec("CREATE TABLE `{$this->prefix}tmp_tz_offset`\n (`timezone` varchar(32) NOT NULL PRIMARY KEY, `offset` char(6) NOT NULL DEFAULT '+00:00') ENGINE={$this->conf['table']['type']}"); foreach ($aTimezones as $tzString => $tzData) { $tzData = $this->_getSqlOffsetFromString($tzData); $this->oDbh->exec("INSERT INTO {$this->prefix}tmp_tz_offset (timezone, offset) VALUES('{$tzString}', '{$tzData}')"); } OA::debug("Created timezone/offset mapping table", PEAR_LOG_DEBUG); // CREATE an ad_id => offset table $this->oDbh->exec("DROP TABLE IF EXISTS {$this->prefix}tmp_ad_offset"); $this->oDbh->exec("CREATE TABLE `{$this->prefix}tmp_ad_offset`\n (`ad_id` int(11) NOT NULL PRIMARY KEY, `offset` char(6) NOT NULL DEFAULT '+00:00') ENGINE={$this->conf['table']['type']}"); $this->oDbh->exec("INSERT INTO {$this->prefix}tmp_ad_offset SELECT bannerid, '{$aAdminTzOffset}' FROM {$this->prefix}banners AS b"); $this->oDbh->exec("UPDATE\n {$this->prefix}tmp_ad_offset AS ao,\n {$this->prefix}banners AS b,\n {$this->prefix}campaigns AS c,\n {$this->prefix}clients AS cl,\n {$this->prefix}agency AS ag,\n {$this->prefix}account_preference_assoc AS apa,\n {$this->prefix}preferences AS p,\n {$this->prefix}tmp_tz_offset AS tzo\n SET ao.offset = tzo.offset\n WHERE\n p.preference_name = 'timezone'\n AND apa.preference_id = p.preference_id\n AND apa.account_id = ag.account_id\n AND cl.agencyid=ag.agencyid\n AND ao.ad_id=b.bannerid\n AND c.campaignid=b.campaignid\n AND cl.clientid=c.clientid\n AND ag.agencyid=cl.agencyid\n AND apa.value = tzo.timezone;\n "); OA::debug("Created ad/offset mapping table", PEAR_LOG_DEBUG); // So, now we have a table tmp_ad_offset which contains every banner id, and the offset of the account it belongs to. // We can use this to do a complex GROUP BY to collapse data down into the user's timzone's midday $this->oDbh->exec("DROP TABLE IF EXISTS {$this->prefix}data_summary_ad_hourly_rolledup"); $this->oDbh->exec("DROP TABLE IF EXISTS {$this->prefix}data_summary_ad_hourly_backup"); // Create a new stats table, we do this because trying to delete a bunch of records from the existing table would just fragment the index $this->oDbh->exec("CREATE TABLE {$this->prefix}data_summary_ad_hourly_rolledup LIKE {$this->prefix}data_summary_ad_hourly;"); // Copy stats over from the existing table to the new table, rolling up according to each ad's offset OA::debug("Beginning rolled-up stats copy...", PEAR_LOG_DEBUG); $this->oDbh->exec("INSERT INTO {$this->prefix}data_summary_ad_hourly_rolledup (\n date_time, ad_id, creative_id, zone_id, requests, impressions, clicks, conversions,\n total_basket_value, total_num_items, total_revenue, total_cost, total_techcost, updated )\n SELECT\n CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(dsah.date_time, '+00:00', ao.offset), '%Y-%m-%d 12:00:00'), ao.offset, '+00:00') AS tz_date_time,\n dsah.ad_id, dsah.creative_id, dsah.zone_id, SUM(dsah.requests), SUM(dsah.impressions), SUM(dsah.clicks), SUM(dsah.conversions),\n SUM(dsah.total_basket_value), SUM(dsah.total_num_items), SUM(dsah.total_revenue), SUM(dsah.total_cost), SUM(dsah.total_techcost), '{$updated}'\n FROM\n {$this->prefix}data_summary_ad_hourly AS dsah,\n {$this->prefix}tmp_ad_offset AS ao\n WHERE\n ao.ad_id=dsah.ad_id\n AND CONVERT_TZ(dsah.date_time, '+00:00', ao.offset) < '{$sDate}'\n GROUP BY\n tz_date_time, ad_id, creative_id, zone_id;\n "); OA::debug("Completed rolled-up stats copy...", PEAR_LOG_DEBUG); // Copy any un-rolled up stats records over into the new table OA::debug("Beginning *non* rolled-up stats copy...", PEAR_LOG_DEBUG); $this->oDbh->exec("INSERT INTO {$this->prefix}data_summary_ad_hourly_rolledup (\n date_time, ad_id, creative_id, zone_id, requests, impressions, clicks, conversions,\n total_basket_value, total_num_items, total_revenue, total_cost, total_techcost, updated)\n SELECT\n dsah.date_time AS tz_date_time, dsah.ad_id, dsah.creative_id, dsah.zone_id, dsah.requests, dsah.impressions, dsah.clicks, dsah.conversions,\n dsah.total_basket_value, dsah.total_num_items, dsah.total_revenue, dsah.total_cost, dsah.total_techcost, '{$updated}'\n FROM\n {$this->prefix}data_summary_ad_hourly AS dsah,\n {$this->prefix}tmp_ad_offset AS ao\n WHERE\n ao.ad_id=dsah.ad_id\n AND CONVERT_TZ(dsah.date_time, '+00:00', ao.offset) >= '{$sDate}'\n "); OA::debug("Completed *non* rolled-up stats copy...", PEAR_LOG_DEBUG); // Swap the old table with the new $this->oDbh->exec("RENAME TABLE {$this->prefix}data_summary_ad_hourly TO {$this->prefix}data_summary_ad_hourly_backup"); $this->oDbh->exec("RENAME TABLE {$this->prefix}data_summary_ad_hourly_rolledup TO {$this->prefix}data_summary_ad_hourly"); OA::debug("Swapped new table for old...", PEAR_LOG_DEBUG); // Cleanup $this->oDbh->exec("DROP TABLE {$this->prefix}tmp_ad_offset;"); $this->oDbh->exec("DROP TABLE {$this->prefix}tmp_tz_offset;"); OA::debug("Woo hoo stats rolled up for pre-{$sDate}", PEAR_LOG_INFO); }
* max_formattedNumberStringToFloat() function when the onSubmit() * event of the field occurs, so that you get un-formatted input * into your form submission script, if said script doesn't deal * with the formatted input. * * * @TODO Add support for dealing with exceeding the upper limit of * JS support for numbers. */ // Require the initialisation file require_once '../../../init.php'; // Required files require_once MAX_PATH . '/lib/max/language/Default.php'; require_once MAX_PATH . '/lib/OA/Preferences.php'; // Load the user preferences from the database $pref = OA_Preferences::loadAdminAccountPreferences(true); // Load the required language files Language_Default::load(); // Send content-type header header("Content-type: application/x-javascript"); // The largest possible integer in when using JavaScript's // default 4-octet storage for numbers define('MAX_JS_INTEGER_UPPER_LIMIT', 9007199254740992); ?> /** * A JavaScript function to take a number, either as a real number, or * as a formatted string represenation of a number, and return that * number as a string, correctly formatted with thousands and decimal * delimiters in the textual representation. *
/** * A private method to load the preferences required when generating reports. * * @access private * @return array The loaded preference array. */ function _loadPrefs() { $aPref = $GLOBALS['_MAX']['PREF']; if (is_null($aPref)) { $aPref = OA_Preferences::loadAdminAccountPreferences(true); } return $aPref; }
function testPutAdmin() { $oUpgrade = new OA_Upgrade(); // Prepare test data $aAdmin = array('email' => '*****@*****.**', 'name' => 'testadmin', 'pword' => 'testpass', 'language' => 'es'); $aPrefs = array('timezone' => 'Europe/Madrid'); // there shouldn't be admin account $adminAccountId = OA_Dal_ApplicationVariables::get('admin_account_id'); $this->assertNull($adminAccountId); // create admin $result = $oUpgrade->putAdmin($aAdmin, $aPrefs); $this->assertTrue($result); // admin account is set $adminAccountId = OA_Dal_ApplicationVariables::get('admin_account_id'); $this->assertNotNull($adminAccountId); $doAccount = OA_Dal::factoryDO('accounts'); $doAccount->get($adminAccountId); $this->assertEqual($doAccount->account_type, OA_ACCOUNT_ADMIN); $this->assertEqual($doAccount->account_name, 'Administrator account'); // user exists $doUser = OA_Dal::factoryDO('users'); $doUserAssoc = OA_Dal::factoryDO('account_user_assoc'); $doUserAssoc->account_id = $adminAccountId; $doUser->joinAdd($doUserAssoc); $doUser->find(); $this->assertTrue($doUser->fetch()); $this->assertEqual($doUser->contact_name, 'Administrator'); $this->assertEqual($doUser->email_address, $aAdmin['email']); $this->assertEqual($doUser->username, $aAdmin['name']); $this->assertEqual($doUser->password, md5($aAdmin['pword'])); $this->assertEqual($doUser->language, $aAdmin['language']); // agency was created $doAgency = OA_Dal::factoryDO('agency'); $doAccount = OA_Dal::factoryDO('accounts'); $doAccount->account_id = $doUser->default_account_id; $doAgency->joinAdd($doAccount); $doAgency->find(); $this->assertTrue($doAgency->fetch()); $this->assertEqual($doAgency->name, 'Default manager'); $this->assertEqual($doAgency->email, $aAdmin['email']); $this->assertEqual($doAgency->active, 1); // Default preferences + custom timezone are set $oPreferences = new OA_Preferences(); $aDefPrefs = $oPreferences->getPreferenceDefaults(); $aExpected = array(); foreach ($aDefPrefs as $name => $values) { $aExpected[$name] = $values['default']; } $aExpected['timezone'] = $aPrefs['timezone']; $aExpected['language'] = 'en'; //added by get admin account preferences $aAdminPreferences = OA_Preferences::loadAdminAccountPreferences(true); $this->assertEqual($aExpected, $aAdminPreferences); // trunkate tables DataGenerator::cleanUp(array('account_preference_assoc', 'preferences', 'account_user_assoc', 'users', 'agency', 'accounts')); // remove admin_account_id from application variables OA_Dal_ApplicationVariables::delete('admin_account_id'); }