public function testTimeGetCurrentGMT(){ $ref = new DateTime(null, new DateTimeZone('UTC')); $this->assertEquals($ref->format('U'), \Time::GetCurrentGMT('U')); $this->assertEquals($ref->format('Y-m-d'), \Time::GetCurrentGMT('Y-m-d')); }
public function set($k, $v) { switch ($k) { case 'status': // Update the published date if it's status has changed. if ($v == $this->get($k)) { return false; } if ($v == 'published' && !$this->get('published')) { parent::set('published', Time::GetCurrentGMT()); } elseif ($v == 'draft' && $this->get('published')) { parent::set('published', ''); } // And resume! return parent::set($k, $v); case 'published': // make sure this is a valid timestamp! if ($v != '' && !is_numeric($v)) { $time = strtotime($v); return parent::set($k, $time); } else { return parent::set($k, $v); } default: return parent::set($k, $v); } }
$md5 = md5_file($dirname . $fname); $allfiles[] = array( 'file' => $fname, 'md5' => $md5, 'controllers' => array($class . 'Controller') ); // Don't forget to create a template directory for any pages on this controller. $dir = new \Core\Filestore\Backends\DirectoryLocal($dirname . 'templates/pages/' . strtolower($class)); $dir->mkdir(); } // Write the changelog $now = Time::GetCurrentGMT(Time::FORMAT_RFC2822); file_put_contents($dirname . 'CHANGELOG', "$componentname 1.0.0 * Initial version "); $allfiles[] = array( 'file' => 'CHANGELOG', 'md5' => md5_file($dirname . 'CHANGELOG') ); // And the readme file_put_contents($dirname . 'README.md', "# About $componentname @todo Write something about this component. ");
/** * Delete this record from the datastore. * * Will IMMEDIATELY remove the record! * * If this model has a "deleted" column that is set as a zero value, that record is set to the current timestamp instead. * This functionality is meant for advanced record tracking such as those in use in sync systems. * * @return bool * @throws Exception */ public function delete() { $classname = get_called_class(); // Allow all supplemental models to tap into this too! if(isset(self::$_ModelSupplementals[$classname])){ foreach(self::$_ModelSupplementals[$classname] as $supplemental){ if(class_exists($supplemental)){ $ref = new ReflectionClass($supplemental); if($ref->hasMethod('PreDeleteHook')){ $ref->getMethod('PreDeleteHook')->invoke(null, $this); } } } } foreach ($this->_columns as $c) { /** @var \Core\Datamodel\Columns\SchemaColumn $c */ // Certain key types have certain functions. if($c->type == Model::ATT_TYPE_DELETED) { // Is this record already set as deleted? // If it is, then proceed with the delete as usual. // Otherwise, update the record instead of deleting it. if(!$c->value){ $nv = Time::GetCurrentGMT(); $this->set($c->field, $nv); return $this->save(); } else{ // I can safely break out of the foreach statement at this stage. break; } } } // Blank out any dependent records based on links. // Since relationships may have various levels, I need to execute delete on each of them instead of just // issuing a broad delete request. foreach ($this->_linked as $k => $l) { switch($l['link']){ case Model::LINK_HASONE: // Delete this child, (and any of its subordinates). $child = $this->getLink($k); $child->delete(); break; case Model::LINK_HASMANY: // Request all the children and issue a delete on them. $children = $this->getLink($k); foreach($children as $child){ /** @var Model $child */ $child->delete(); } break; // There is no default behaviour... other than to ignore it. } if (isset($this->_linked[$k]['records'])) unset($this->_linked[$k]['records']); } if ($this->exists()) { // Check and see if this model extends another model. // If it does, then create/update that parent object to keep it in sync! if(($class = get_parent_class($this)) != 'Model'){ $idx = self::GetIndexes(); if(isset($idx['primary']) && sizeof($idx['primary']) == 1){ $schema = $this->getKeySchema($idx['primary'][0]); if($schema['type'] == Model::ATT_TYPE_UUID){ $refp = new ReflectionClass($class); $refm = $refp->getMethod('Construct'); /** @var Model $parent */ $parent = $refm->invoke(null, $this->get($idx['primary'][0])); $parent->delete(); } } } $n = $this->_getTableName(); $i = self::GetIndexes(); // Delete the data from the database. $dat = new Core\Datamodel\Dataset(); $dat->table($n); if (!isset($i['primary'])) { throw new Exception('Unable to delete model [ ' . get_class($this) . ' ] without any primary keys.'); } $pri = $i['primary']; if(!is_array($pri)) $pri = [$pri]; foreach ($pri as $k) { $dat->where([$k => $this->get($k)]); } $dat->limit(1)->delete(); if ($dat->execute($this->interface)) { $this->_exists = false; } } return true; }
/** * Cleanup any expired sessions from the database. * * @return bool Always returns true :) */ public static function CleanupExpired(){ static $lastexecuted = 0; /** * Delete ANY session that has expired. */ $ttl = \ConfigHandler::Get('/core/session/ttl'); $datetime = (\Time::GetCurrentGMT() - $ttl); if($lastexecuted == $datetime){ // This operation was already called this second. No need to do it again. // This is used because if a LOT of user operations occur on a given page, // this method may be called many many many times. return true; } // Low-level datasets are used here because they have less overhead than // the full-blown model system. $dataset = new Datamodel\Dataset(); $dataset->table('session'); $dataset->where('updated < ' . $datetime); $dataset->delete()->execute(); $lastexecuted = $datetime; // Always return TRUE return true; }
/** * Execute the actual cron for the requested type. * * @param string $cron Cron type to execute. * * @return CronLogModel * @throws Exception */ private function _performcron($cron) { switch ($cron) { case '1-minute': case '5-minute': case '15-minute': case '30-minute': case 'hourly': case '2-hour': case '3-hour': case '6-hour': case '12-hour': case 'daily': case 'weekly': case 'monthly': break; default: throw new Exception('Unsupported cron type: [' . $cron . ']'); } if (!ConfigHandler::Get('/cron/enabled')) { $msg = 'Cron execution is globally disabled via the site configuration, not executing cron!'; SystemLogModel::LogInfoEvent('/cron/' . $cron, $msg); // It needs to return something. $log = new CronLogModel(); $log->set('status', 'fail'); return $log; } // First, check and see if there's one that's still running. $runninglogs = CronLogModel::Find(array('cron' => $cron, 'status' => 'running')); if (sizeof($runninglogs)) { foreach ($runninglogs as $log) { /** @var $log CronLogModel */ $log->set('status', 'fail'); $log->set('log', $log->get('log') . "\n------------\nTIMED OUT!"); $log->save(); } } // Start recording. $log = new CronLogModel(); $log->set('cron', $cron); $log->set('status', 'running'); $log->set('memory', memory_get_usage()); $log->set('ip', REMOTE_IP); $log->save(); $start = microtime(true) * 1000; $sep = '==========================================' . "\n"; $contents = "Starting cron execution for {$cron}\n{$sep}"; // This uses the hook system, but will be slightly different than most things. $overallresult = true; $hook = HookHandler::GetHook('/cron/' . $cron); $hookcount = 0; $hooksuccesses = 0; if ($hook) { if ($hook->getBindingCount()) { $hookcount = $hook->getBindingCount(); $bindings = $hook->getBindings(); foreach ($bindings as $b) { $contents .= sprintf("\nExecuting Binding %s...\n", $b['call']); // Since these systems will just be writing to STDOUT, I'll need to capture that. try { ob_start(); $execution = $hook->callBinding($b, array()); $executiondata = ob_get_clean(); } catch (Exception $e) { $execution = false; $executiondata = 'EXCEPTION: ' . $e->getMessage() . ob_get_clean(); } if ($executiondata == '' && $execution) { $contents .= "Cron executed successfully with no output\n"; ++$hooksuccesses; } elseif ($execution) { $contents .= $executiondata . "\n"; ++$hooksuccesses; } else { $contents .= $executiondata . "\n!!FAILED\n"; $overallresult = false; } } } else { $contents = 'No bindings located for requested cron'; $overallresult = true; } } else { $contents = 'Invalid hook requested: ' . $cron; $overallresult = false; } // Just in case the contents are returning html... (they should be plain text). // Replace the most common line endings with things that make sense for plain text. // This is to ensure that all the available scenarios are met and saved/displayed without extra whitespace. // // Since some systems will provide plain text (easy!), windows/os9 line endings, // HTML (br and br/), and formatted HTML (br + \n). $contents = str_ireplace(["\r\n<br>", "\r\n<br/>", "\r\n<br />", "\n<br>", "\n<br/>", "\n<br />", "<br>", "<br/>", "<br />", "\r\n", "\r"], "\n", $contents); // Save the results. $log->set('completed', Time::GetCurrentGMT()); $log->set('duration', microtime(true) * 1000 - $start); $log->set('log', $contents); $log->set('status', $overallresult ? 'pass' : 'fail'); $log->save(); // Make a copy of this in the system log too if applicable. // This time is listed in ms $time = microtime(true) * 1000 - $start; // 0.01 = 10 ns // 1 = 1 ms // 1000 = 1 second if ($time < 1) { // TIME is less than 1, which means it executed faster than 1ms, display in nanoseconds. $time = round($time, 4) * 1000 . ' ns'; } elseif ($time < 1000) { // TIME is less than 1000, which means it executed faster than 1 second, display in milliseconds. $time = round($time, 0) . ' ms'; } else { // TIME is at least 1 second or longer... Display in minutes:seconds, (no need to display 1.453 seconds!) // First, convert the milliseconds to seconds; they are more manageable for what I need to do. // This will change time from 12345(ms) to 13(seconds) $time = ceil($time / 1000); $minutes = floor($time / 60); $seconds = $time - $minutes * 60; if ($minutes > 0) { $time = $minutes . 'm ' . str_pad($seconds, 2, '0', STR_PAD_LEFT) . 's'; } else { $time = $seconds . ' seconds'; } } if ($hookcount > 0) { $msg = 'Cron ' . $cron . ' completed in ' . $time . '. ' . $hooksuccesses . ' out of ' . $hookcount . ' hooks called successfully.'; SystemLogModel::LogInfoEvent('/cron/' . $cron, $msg, $contents); } // Just to notify the calling function. return $log; }
<?php /** * Upgrade file for user data from 2.6.1 to 2.6.2. * * Namely setting the last login for users that have a password set. * It's good indication that if they have a password set, that they've logged in already. * * @author Charlie Powell <*****@*****.**> * @date 20131030.2031 * @package Core */ $timenow = Time::GetCurrentGMT(); // Find and update all user accounts that have a last login of not recorded, but have a password set (legacy data) $users = UserModel::Find(['password != ', 'last_login = 0']); foreach($users as $u){ /** @var $u UserModel */ $u->set('last_login', $timenow); $u->save(); } // Find and update all user accounts that have a last login of not recorded, but have a password set (legacy data) $users = UserModel::Find(['password != ', 'last_password = 0']); foreach($users as $u){ /** @var $u UserModel */ $u->set('last_password', $timenow); $u->save(); }
/** * Helper function to save a blog article, both new and existing. * * @static * * @param Form $form * @return string Redirect URL */ public static function BlogArticleFormHandler(Form $form) { try { /** @var $page PageModel */ $page = $form->getModel('page'); /** @var $article BlogArticleModel */ $article = $form->getModel('model'); // I need to update some of the article information from the page info. $article->set('title', $page->get('title')); /** @var $pageauthor PageMetaModel|null */ $pageauthor = $page->getMeta('author'); if ($pageauthor && $pageauthor->get('meta_value_title') && $pageauthor->get('meta_value')) { // Allow the user to override who is posting this article, if set. $article->set('authorid', $pageauthor->get('meta_value')); } elseif ($pageauthor && $pageauthor->get('meta_value_title')) { // If they never selected a valid user, allow that to go through too. // The page will have saved the name that they type in regardless. $article->set('authorid', 0); } else { // Otherwise Set the article author to the current user. $article->set('authorid', \Core\user()->get('id')); $page->setMeta('author', \Core\user()->getDisplayName()); $page->setMeta('authorid', \Core\user()->get('id')); } $isnew = !$article->exists(); // Blog pages are not selectable. Otherwise there would just be WAY too many of them! // This addresses bug #321 $page->set('selectable', 0); if ($article->get('status') == 'published' && !$article->get('published')) { // If it's new and is published... set the published date to right now! $article->set('published', Time::GetCurrentGMT()); } $article->save(); // Set the baseurl and some other data on the page $page->set('baseurl', $article->get('baseurl')); $page->set('component', 'blog'); $page->set('editurl', '/blog/article/update/' . $article->get('blogid') . '/' . $article->get('id')); $page->save(); // Clear the page cache $page->purgePageCache(); // if it's new, allow the user to post it to facebook. if (isset($_POST['facebook_post']) && $_POST['facebook_post']) { // facebook_post $token = substr($_POST['facebook_post'], strpos($_POST['facebook_post'], ':') + 1); $fbid = substr($_POST['facebook_post'], 0, strpos($_POST['facebook_post'], ':')); $from = \Core\user()->get('facebook_id'); // yay.... $args = array('access_token' => $token, 'from' => $from, 'link' => \Core\resolve_link($article->get('rewriteurl')), 'name' => $article->get('title'), 'caption' => '', 'description' => $article->getTeaser(), 'message' => ''); // Some optional arguments if ($article->getImage()) { $args['picture'] = $article->getImage()->getPreviewURL('300x300'); } $args['ref'] = 'coreplus'; $facebook = new Facebook(array('appId' => FACEBOOK_APP_ID, 'secret' => FACEBOOK_APP_SECRET)); $publish_result = $facebook->api('/' . $fbid . '/feed', 'POST', $args); $article->set('fb_account_id', $fbid); $article->set('fb_post_id', $publish_result['id']); $article->save(); } Core::SetMessage(($isnew ? 'Created' : 'Updated') . ' blog article successfully!', 'success'); return 'back'; //return $article->get('baseurl'); } catch (ModelValidationException $e) { Core::SetMessage($e->getMessage(), 'error'); return false; } catch (FacebookApiException $e) { // Facebook errors are not critical, as the post is still created. Core::SetMessage($e->getMessage(), 'error'); return $article->get('rewriteurl'); } catch (Exception $e) { \Core\ErrorManagement\exception_handler($e); Core::SetMessage($e->getMessage(), 'error'); return false; } }