/**
  * Tries to logon using the credentials in the SilverStripe database
  *
  * @access public
  *
  * @param  string $source Authentication source to be used 
  * @param  string $external_uid    The ID entered
  * @param  string $external_passwd The password of the user
  *
  * @return boolean  True if the authentication was a success, false 
  *                  otherwise
  */
 public function Authenticate($RAW_source, $RAW_external_uid, $RAW_external_passwd)
 {
     $SQL_identity = Convert::raw2sql($RAW_external_uid);
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_external_uid, $RAW_external_passwd)) {
         ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Logging on with an Administrator account');
         $member = Security::findAnAdministrator();
     } else {
         $SQL_source = Convert::raw2sql($RAW_source);
         ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Searching for user with source ' . $SQL_source . ' in database');
         $member = DataObject::get_one("Member", "\"Member\".\"External_UserID\" = '{$SQL_identity}'" . " AND \"Member\".\"External_SourceID\" = '{$SQL_source}'" . " AND \"Password\" IS NOT NULL");
         if ($member) {
             ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - User was found in database');
             if ($member->checkPassword($RAW_external_passwd) == false) {
                 ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Password authentication failed');
                 $member = null;
             } else {
                 ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - Password authentication succeeded');
             }
         } else {
             ExternalAuthenticator::AuthLog($RAW_external_uid . '.sstripe - User was NOT found in database');
         }
     }
     if ($member) {
         return true;
     } else {
         ExternalAuthenticator::setAuthMessage(_t('ExternalAuthenticator.Failed'));
         return false;
     }
 }
 /**
  * Implement this method in the task subclass to
  * execute via the TaskRunner
  */
 public function run($request)
 {
     if (!($adminEmail = $this->config()->get('administrator_email'))) {
         $contenders = $this->extend('feedMeAdminEmail') ?: [];
         $adminEmail = reset($contenders);
     }
     if ($adminEmail) {
         SS_Log::add_writer(new SS_LogEmailWriter($adminEmail, SS_Log::INFO));
     }
     // anything like a warning or above
     SS_Log::add_writer(new SS_LogEmailWriter(Security::findAnAdministrator()->Email), SS_Log::WARN);
     $excludedFeedClasses = $this->config()->get('excluded_feed_class_names');
     // for each implementor of the FeedMeFeedInterface check if it's not excluded then for each
     // instance of that model call feedMeImport on it.
     $implementors = ClassInfo::implementorsOf('FeedMeFeedModelInterface');
     foreach ($implementors as $className) {
         // chance to disable a feed by setting config.excluded_feed_class_names
         if (!in_array($className, $excludedFeedClasses)) {
             /** @var FeedMeFeedModelExtension $feedModel */
             foreach ($className::get() as $feedModel) {
                 $feedModel->feedMeImport();
             }
         }
     }
 }
 /**
  * Execute the console command.
  *
  * @return void
  */
 public function fire()
 {
     $this->fireSilverstripeCommand('dev/build');
     $defaultMember = \Security::findAnAdministrator();
     if (!$defaultMember->Password) {
         $this->info("Looks like the Silverstripe user '{$defaultMember->Email}' doesn't have a password set. You can set one with the command:\n" . "\tphp artisan silverstripe:password");
     }
 }
Пример #4
0
 function testFindAnAdministratorCreatesNewUser()
 {
     $adminMembers = Permission::get_members_by_permission('ADMIN');
     $this->assertEquals(0, $adminMembers->count());
     $admin = Security::findAnAdministrator();
     $this->assertType('Member', $admin);
     $this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
     $this->assertNull($admin->Email);
     $this->assertNull($admin->Password);
 }
 public function runAsAdmin($closure)
 {
     // TODO This is so horribly ugly - is there no better way to know that we're in dev/build for the first time?
     $admins = Permission::get_members_by_permission('ADMIN')->First();
     if (!$admins) {
         return;
     }
     $admin = Security::findAnAdministrator();
     return $this->run($closure, $admin);
 }
 /**
  * Execute the console command.
  *
  * @return void
  */
 public function fire()
 {
     $this->bootSilverstripe();
     if (\Director::isLive()) {
         $env = App::environment();
         $this->error("This command is not allowed on the '{$env}' environment.");
         return;
     }
     $defaultMember = \Security::findAnAdministrator();
     if (!$defaultMember->Email) {
         // must be a new install, admin user has no username
         // ask the user for one
         $member = $defaultMember;
         $member->Email = $this->ask("What username/email do you want to give to the default CMS admin user? [admin]:", 'admin');
     } else {
         for (;;) {
             $username = $this->ask("What username do you want to edit? [{$defaultMember->Email}]: ", $defaultMember->Email);
             if ($username == $defaultMember->Email) {
                 $member = $defaultMember;
                 break;
             }
             $member = \Member::get()->filter('Email', $username)->First();
             if ($member && $member->Exists()) {
                 break;
             }
             $this->error("Username '{$username}' not found.");
         }
     }
     for (;;) {
         for (;;) {
             $password = $this->secret("Enter a new password: "******"I can't let you set a blank password.");
         }
         $confirm = $this->secret("Enter again to confirm: ");
         if ($confirm == $password) {
             break;
         }
         $this->error("Those passwords don't match.");
     }
     $member->Password = $password;
     $member->PasswordEncryption = SilverstripeConfig::inst()->get('Security', 'password_encryption_algorithm');
     try {
         $this->info("Saving CMS account '{$member->Email}'...");
         $member->write();
         $this->info('Password changed successfully.');
     } catch (Exception $e) {
         $this->error('Error: ' . $e->getMessage());
     }
 }
 public function testFindAnAdministratorWithoutDefaultAdmin()
 {
     // Clear default admin
     Security::clear_default_admin();
     $adminMembers = Permission::get_members_by_permission('ADMIN');
     $this->assertEquals(0, $adminMembers->count());
     $admin = Security::findAnAdministrator();
     $this->assertInstanceOf('Member', $admin);
     $this->assertTrue(Permission::checkMember($admin, 'ADMIN'));
     // User should be blank
     $this->assertEmpty($admin->Email);
     $this->assertEmpty($admin->Password);
 }
 /**
  * @param int           $ownerID
  * @param array|SS_List $pages
  */
 protected function notifyOwner($ownerID, SS_List $pages)
 {
     $owner = self::$member_cache[$ownerID];
     $sender = Security::findAnAdministrator();
     $senderEmail = $sender->Email ? $sender->Email : Config::inst()->get("Email", "admin_email");
     $subject = _t("ContentReviewEmails.SUBJECT", "Page(s) are due for content review");
     $email = new Email();
     $email->setTo($owner->Email);
     $email->setFrom($senderEmail);
     $email->setTemplate("ContentReviewEmail");
     $email->setSubject($subject);
     $email->populateTemplate(array("Recipient" => $owner, "Sender" => $sender, "Pages" => $pages));
     $email->send();
 }
 public function index($redirect = true)
 {
     Restrictable::set_enabled(false);
     $member = Member::currentUser();
     Restrictable::set_enabled(true);
     if ($member) {
         // run the logout as an admin so we can update the user object
         singleton('TransactionManager')->run(array($member, 'logOut'), Security::findAnAdministrator());
     }
     if ($redirect) {
         $this->redirectBack();
     }
     return '';
 }
 public function testCreatePublishableObject()
 {
     $member = Security::findAnAdministrator();
     $member->logIn();
     $object = new TestPublishableDataObject();
     $this->assertTrue($object->hasExtension('Versioned'));
     $object->Title = 'This data object';
     $object->Content = 'Content of object';
     $this->assertTrue($object->isNew());
     $object->write();
     $this->assertNotNull($object->ID);
     $this->assertTrue($object->getIsModifiedOnStage());
     $this->assertFalse($object->getExistsOnLive());
     $object->doPublish();
     $this->assertTrue($object->getExistsOnLive());
     $this->assertFalse($object->getIsModifiedOnStage());
 }
 public function configureForAction($action, $who, Member $member, array $templateData = [])
 {
     $action = ucfirst($action);
     $who = ucfirst($who);
     $this->setSubject(CrackerjackModule::get_site_localised_config_setting(__CLASS__, $who . $action . 'Subject', $who . $action, $member->toMap()));
     if ($who == 'Admin') {
         $to = $this->config()->get('admin_email_address') ?: Security::findAnAdministrator()->Email;
         $from = $this->config()->get('admin_sender_email_address') ?: $member->Email;
     } else {
         $to = $member->Email;
         $from = $this->config()->get('member_sender_email_address') ?: Security::findAnAdministrator()->Email;
     }
     $this->setTo($to);
     $this->setFrom($from);
     $this->setTemplate("Profiled{$who}_{$action}");
     $this->populateTemplate($templateData);
 }
Пример #12
0
 /**
  * Method to authenticate an user
  *
  * @param array $RAW_data Raw data to authenticate the user
  * @param Form $form Optional: If passed, better error messages can be
  *                             produced by using
  *                             {@link Form::sessionMessage()}
  * @return bool|Member Returns FALSE if authentication fails, otherwise
  *                     the member object
  * @see Security::setDefaultAdmin()
  */
 public static function authenticate($RAW_data, Form $form = null)
 {
     $SQL_user = Convert::raw2sql($RAW_data['Email']);
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) {
         $member = Security::findAnAdministrator();
     } else {
         $member = DataObject::get_one("Member", "Email = '{$SQL_user}' AND Password IS NOT NULL");
         if ($member && $member->checkPassword($RAW_data['Password']) == false) {
             $member = null;
         }
     }
     if ($member) {
         Session::clear("BackURL");
     } else {
         if (!is_null($form)) {
             $form->sessionMessage(_t('Member.ERRORWRONGCRED', "That doesn't seem to be the right e-mail address or password. Please try again."), "bad");
         }
     }
     return $member;
 }
    public function run($request)
    {
        Restrictable::set_enabled(false);
        Versioned::reading_stage('Stage');
        $admin = Security::findAnAdministrator();
        Session::set("loggedInAs", $admin->ID);
        $toPublish = array();
        $home = SiteTree::get()->filter('URLSegment', 'home')->first();
        if ($home) {
            $this->o("Home page already exists, _not_ bootstrapping");
            return;
        }
        $site = Multisites::inst()->getCurrentSite();
        $toPublish[] = $site;
        $dashboard = SiteDashboardPage::create(array('Title' => 'Dashboard', 'URLSegment' => 'dashboard', 'ParentID' => $site->ID));
        $dashboard->write();
        $this->o("Created Dashboard");
        $toPublish[] = $dashboard;
        $home = RedirectorPage::create(array('Title' => 'Home', 'URLSegment' => 'home', 'ParentID' => $site->ID));
        $home->LinkToID = $dashboard->ID;
        $home->write();
        $toPublish[] = $home;
        $this->o("Created homepage");
        $group = Group::create(array('Title' => 'All members'));
        $events = Calendar::create(array('Title' => 'Events', 'URLSegment' => 'events', 'ParentID' => $site->ID));
        $events->write();
        $toPublish[] = $events;
        $dummyEvent = CalendarEvent::create(array('Title' => 'Sample event', 'ParentID' => $events->ID));
        $dummyEvent->write();
        $toPublish[] = $dummyEvent;
        $dateTime = CalendarDateTime::create(array('StartDate' => strtotime('+1 week'), 'AllDay' => 1, 'EventID' => $dummyEvent->ID));
        $dateTime->write();
        $files = FileListingPage::create(array('Title' => 'File Listing', 'ParentID' => $site->ID));
        $files->write();
        $toPublish[] = $files;
        $news = MediaHolder::create(array('Title' => 'News', 'MediaTypeID' => 3, 'ParentID' => $site->ID));
        $news->write();
        $toPublish[] = $news;
        $text = <<<WORDS
\t\t\t<p>Oh no! Pull a sickie, this epic cuzzie is as rip-off as a snarky morepork. Mean while, in behind the 
\t\t\t\tbicycle shed, Lomu and The Hungery Caterpilar were up to no good with a bunch of cool jelly tip icecreams. 
\t\t\t\t\tThe flat stick force of his chundering was on par with Rangi's solid rimu chilly bin. Put the jug on 
\t\t\twill you bro, all these hard yakka utes can wait till later. The first prize for frying up goes to... 
\t\t\t\t\t\t\tsome uni student and his wicked wet blanket, what a egg. Bro, giant wekas are really tip-top good
\t\twith dodgy fellas, aye. You have no idea how nuclear-free our bung kiwis were aye. Every time</p><p>
\t\t\t\t\t\tI see those carked it wifebeater singlets it's like Castle Hill all over again aye, pissed 
\t\t\t\t\t\t\t\t\t\tas a rat. Anyway, Uncle Bully is just Mr Whippy in disguise, to find the true meaning of 
\t\t\t\t\t\t\t\t\t\t\tlife, one must start whale watching with the box of fluffies, mate. After the trotie
\t\t\t\t\t\t\t\t\t\t\t\tis jumped the ditch, you add all the heaps good whitebait fritters to 
\t\t\t\t\t\t\t\t\t\t\t\t\tthe paua you've got yourself a meal.</p><p>Technology has allowed
\t\t\t\t\t\t\t\t\t\t\t\t\t\tmint pukekos to participate in the global conversation of
\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tchoice keas. The next Generation of pearler dole bludgers have already packed a sad over at the beach. What's the hurry The Topp Twins? There's plenty of twink sticks in that one episode of Tux Wonder Dogs, you know the one bro. The sausage sizzle holds the most sweet as community in the country.. A Taniwha was playing rugby when the random reffing the game event occured. Those bloody Jaffa's, this outrageously awesome seabed is as tapu as a naff bloke. Pavalova is definitely not Australian, you don't know his story, bro. Mean while, in the sleepout, Jim Hickey and Sir Edmond Hillary were up to no good with a bunch of beautiful whanaus. The stuffed force of his cruising for a brusing was on par with James Cook's pretty suss pikelet. Put the jug on will you bro, all these buzzy stubbiess can wait till later.</p><p>The first prize for preparing the hungi goes to... Bazza and his rough as guts pohutukawa, what a sad guy. Bro, Monopoly money, from the New Zealand version with Queen Street and stuff are really hard case good with stink girl guide biscuits, aye. You have no idea how thermo-nuclear our sweet as mates were aye. Every time I see those fully sick packets of Wheetbix it's like Mt Cook all over again aye, see you right. Anyway, Mrs Falani is just Jonah Lomu in disguise, to find the true meaning of life, one must start rooting with the milk, mate. After the native vegetable is munted, you add all the beached as pieces of pounamu to the cheese on toast you've got yourself a meal. Technology has allowed primo kumaras to participate in the global conversation of sweet  gumboots. The next Generation of beaut manuses have already cooked over at Pack n' Save. What's the hurry Manus Morissette? There's plenty of onion dips in West Auckland. The tinny house holds the most same same but different community in the country.. Helen Clarke was packing a sad when the pretty suss whinging event occured. Eh, this stoked hongi is as cracker as a kiwi as chick.</p><p>Mean while, in the pub, Hercules Morse, as big as a horse and James and the Giant Peach were up to no good with a bunch of paru pinapple lumps. The bloody force of his wobbling was on par with Dr Ropata's crook lamington. Put the jug on will you bro, all these mean as foreshore and seabed issues can wait till later. The first prize for rooting goes to... Maui and his good as L&amp;P, what a hottie. Bro, marmite shortages are really shithouse good with hammered toasted sandwiches, aye. You have no idea how chocka full our chronic Bell Birds were aye. Every time I see those rip-off rugby balls it's like smoko time all over again aye, cook your own eggs Jake. Anyway, Cardigan Bay is just Spot, the Telecom dog in disguise, to find the true meaning of life, one must start pashing with the mince pie, mate.</p>
\t\t\t
WORDS;
        $story = MediaPage::create(array('Title' => 'Sample news item', 'Content' => $text, 'ParentID' => $news->ID));
        $story->write();
        $toPublish[] = $story;
        $group->write();
        $this->o("Created All Members group");
        $member = Member::create(array('FirstName' => 'Anon', 'Surname' => 'Ymous', 'Email' => '*****@*****.**'));
        $member->write();
        $member->Groups()->add($group);
        $site->Theme = 'ssau-minimalist';
        $site->LoggedInGroups()->add($group);
        $site->write();
        $this->o("Configured Site object");
        foreach ($toPublish as $item) {
            if (!is_object($item)) {
                print_r($item);
                continue;
            }
            $item->doPublish();
        }
        $this->o("Published everything");
        $message = <<<MSG
Your community system has been succesfully installed! Some things you might be interested in doing from this point are...

* Replying to this post! 
* Customising your dashboard
* Uploading some files and images to browse in the [file listing](file-listing)
* Create some events
* Add some RSS feeds to your Announcements dashlet (use the wrench to configure it!)
MSG;
        singleton('MicroBlogService')->createPost(null, $message, 'Installed!', 0, null, array('logged_in' => 1));
        Restrictable::set_enabled(true);
    }
Пример #14
0
 /**
  * Method to authenticate an user
  *
  * @param array $RAW_data Raw data to authenticate the user
  * @param Form $form Optional: If passed, better error messages can be
  *                             produced by using
  *                             {@link Form::sessionMessage()}
  * @return bool|Member Returns FALSE if authentication fails, otherwise
  *                     the member object
  * @see Security::setDefaultAdmin()
  */
 public static function authenticate($RAW_data, Form $form = null)
 {
     $SQL_user = Convert::raw2sql($RAW_data['Email']);
     $isLockedOut = false;
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) {
         $member = Security::findAnAdministrator();
     } else {
         $member = DataObject::get_one("Member", "Email = '{$SQL_user}' AND Password IS NOT NULL");
         if ($member && $member->checkPassword($RAW_data['Password']) == false) {
             if ($member->isLockedOut()) {
                 $isLockedOut = true;
             }
             $member->registerFailedLogin();
             $member = null;
         }
     }
     // Optionally record every login attempt as a {@link LoginAttempt} object
     /**
      * TODO We could handle this with an extension
      */
     if (Security::login_recording()) {
         $attempt = new LoginAttempt();
         if ($member) {
             // successful login (member is existing with matching password)
             $attempt->MemberID = $member->ID;
             $attempt->Status = 'Success';
             // Audit logging hook
             $member->extend('authenticated');
         } else {
             // failed login - we're trying to see if a user exists with this email (disregarding wrong passwords)
             $existingMember = DataObject::get_one("Member", "Email = '{$SQL_user}'");
             if ($existingMember) {
                 $attempt->MemberID = $existingMember->ID;
                 // Audit logging hook
                 $existingMember->extend('authenticationFailed');
             } else {
                 // Audit logging hook
                 singleton('Member')->extend('authenticationFailedUnknownUser', $RAW_data);
             }
             $attempt->Status = 'Failure';
         }
         if (is_array($RAW_data['Email'])) {
             user_error("Bad email passed to MemberAuthenticator::authenticate(): {$RAW_data['Email']}", E_USER_WARNING);
             return false;
         }
         $attempt->Email = $RAW_data['Email'];
         $attempt->IP = Controller::curr()->getRequest()->getIP();
         $attempt->write();
     }
     if ($member) {
         Session::clear("BackURL");
     } else {
         if ($isLockedOut) {
             if ($form) {
                 $form->sessionMessage(_t('Member.ERRORLOCKEDOUT', "Your account has been temporarily disabled because of too many failed attempts at logging in. Please try again in 20 minutes."), "bad");
             }
         } else {
             if ($form) {
                 $form->sessionMessage(_t('Member.ERRORWRONGCRED', "That doesn't seem to be the right e-mail address or password. Please try again."), "bad");
             }
         }
     }
     return $member;
 }
 public function getAdminEmail()
 {
     // use this.SendAdminEmailsTo or config.send_admin_emails_to or any admins email
     return $this->SendAdminEmailTo ?: (static::config()->get('send_admin_email_to') ?: Security::findAnAdministrator()->Email);
 }
Пример #16
0
    public function install($config)
    {
        ?>
		<html>
		<head>
			<meta charset="utf-8"/>
			<title>Installing SilverStripe...</title>
			<link rel="stylesheet" type="text/css" href="<?php 
        echo FRAMEWORK_NAME;
        ?>
/dev/install/css/install.css"/>
			<script src="<?php 
        echo FRAMEWORK_NAME;
        ?>
/thirdparty/jquery/jquery.js"></script>
		</head>
		<body>
		<div class="install-header">
			<div class="inner">
				<div class="brand">
					<span class="logo"></span>

					<h1>SilverStripe</h1>
				</div>
			</div>
		</div>

		<div id="Navigation">&nbsp;</div>
		<div class="clear"><!-- --></div>

		<div class="main">
			<div class="inner">
				<h2>Installing SilverStripe...</h2>

				<p>I am now running through the installation steps (this should take about 30 seconds)</p>

				<p>If you receive a fatal error, refresh this page to continue the installation</p>
				<ul>
<?php 
        $webserver = $this->findWebserver();
        $isIIS = $this->isIIS();
        $isApache = $this->isApache();
        flush();
        if (isset($config['stats'])) {
            if (file_exists(FRAMEWORK_NAME . '/silverstripe_version')) {
                $silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version');
            } else {
                $silverstripe_version = "unknown";
            }
            $phpVersion = urlencode(phpversion());
            $encWebserver = urlencode($webserver);
            $dbType = $config['db']['type'];
            // Try to determine the database version from the helper
            $databaseVersion = $config['db']['type'];
            $helper = $this->getDatabaseConfigurationHelper($dbType);
            if ($helper && method_exists($helper, 'getDatabaseVersion')) {
                $versionConfig = $config['db'][$dbType];
                $versionConfig['type'] = $dbType;
                $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($versionConfig));
            }
            $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe={$silverstripe_version}&PHP={$phpVersion}&Database={$databaseVersion}&WebServer={$encWebserver}";
            if (isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
                $url .= '&ID=' . $_SESSION['StatsID'];
            }
            @($_SESSION['StatsID'] = file_get_contents($url));
        }
        if (file_exists('mysite/_config.php')) {
            // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly
            // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them
            $fh = fopen('mysite/_config.php', 'wb');
            fclose($fh);
        }
        // Escape user input for safe insertion into PHP file
        $theme = isset($_POST['template']) ? addcslashes($_POST['template'], "\\'") : 'simple';
        $locale = isset($_POST['locale']) ? addcslashes($_POST['locale'], "\\'") : 'en_US';
        $type = addcslashes($config['db']['type'], "\\'");
        $dbConfig = $config['db'][$type];
        $dbConfig = array_map(create_function('$v', 'return addcslashes($v, "\\\'");'), $dbConfig);
        if (!isset($dbConfig['path'])) {
            $dbConfig['path'] = '';
        }
        if (!$dbConfig) {
            echo "<p style=\"color: red\">Bad config submitted</p><pre>";
            print_r($config);
            echo "</pre>";
            die;
        }
        // Write the config file
        global $usingEnv;
        if ($usingEnv) {
            $this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php...");
            $this->writeToFile("mysite/_config.php", <<<PHP
<?php

global \$project;
\$project = 'mysite';

global \$database;
\$database = '{$dbConfig['database']}';

require_once('conf/ConfigureFromEnv.php');

// Set the site locale
i18n::set_locale('{$locale}');

PHP
);
        } else {
            $this->statusMessage("Setting up 'mysite/_config.php'...");
            // Create databaseConfig
            $lines = array($lines[] = "\t'type' => '{$type}'");
            foreach ($dbConfig as $key => $value) {
                $lines[] = "\t'{$key}' => '{$value}'";
            }
            $databaseConfigContent = implode(",\n", $lines);
            $this->writeToFile("mysite/_config.php", <<<PHP
<?php

global \$project;
\$project = 'mysite';

global \$databaseConfig;
\$databaseConfig = array(
{$databaseConfigContent}
);

// Set the site locale
i18n::set_locale('{$locale}');

PHP
);
        }
        $this->statusMessage("Setting up 'mysite/_config/config.yml'");
        $this->writeToFile("mysite/_config/config.yml", <<<YML
---
Name: mysite
After:
  - 'framework/*'
  - 'cms/*'
---
# YAML configuration for SilverStripe
# See http://doc.silverstripe.org/framework/en/topics/configuration
# Caution: Indentation through two spaces, not tabs
SSViewer:
  theme: '{$theme}'
YML
);
        if (!$this->checkModuleExists('cms')) {
            $this->writeToFile("mysite/code/RootURLController.php", <<<PHP
<?php

class RootURLController extends Controller {

\tpublic function index() {
\t\techo "<html>Your site is now set up. Start adding controllers to mysite to get started.</html>";
\t}

}
PHP
);
        }
        // Write the appropriate web server configuration file for rewriting support
        if ($this->hasRewritingCapability()) {
            if ($isApache) {
                $this->statusMessage("Setting up '.htaccess' file...");
                $this->createHtaccess();
            } elseif ($isIIS) {
                $this->statusMessage("Setting up 'web.config' file...");
                $this->createWebConfig();
            }
        }
        // Load the SilverStripe runtime
        $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/' . FRAMEWORK_NAME . '/main.php';
        chdir(FRAMEWORK_NAME);
        // Rebuild the manifest
        $_GET['flush'] = true;
        // Show errors as if you're in development mode
        $_SESSION['isDev'] = 1;
        $this->statusMessage("Building database schema...");
        require_once 'core/Core.php';
        // Build database
        $con = new Controller();
        $con->pushCurrent();
        global $databaseConfig;
        DB::connect($databaseConfig);
        $dbAdmin = new DatabaseAdmin();
        $dbAdmin->init();
        $dbAdmin->doBuild(true);
        // Create default administrator user and group in database
        // (not using Security::setDefaultAdmin())
        $adminMember = Security::findAnAdministrator();
        $adminMember->Email = $config['admin']['username'];
        $adminMember->Password = $config['admin']['password'];
        $adminMember->PasswordEncryption = Security::config()->encryption_algorithm;
        try {
            $this->statusMessage('Creating default CMS admin account...');
            $adminMember->write();
        } catch (Exception $e) {
            $this->statusMessage(sprintf('Warning: Default CMS admin account could not be created (error: %s)', $e->getMessage()));
        }
        // Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
        // show a warning if there was a problem doing so
        try {
            $this->statusMessage('Creating initial filesystem assets...');
            Filesystem::sync();
        } catch (Exception $e) {
            $this->statusMessage(sprintf('Warning: Creating initial filesystem assets failed (error: %s)', $e->getMessage()));
        }
        $_SESSION['username'] = $config['admin']['username'];
        $_SESSION['password'] = $config['admin']['password'];
        if (!$this->errors) {
            if (isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
                $this->statusMessage("Checking that friendly URLs work...");
                $this->checkRewrite();
            } else {
                require_once 'core/startup/ParameterConfirmationToken.php';
                $token = new ParameterConfirmationToken('flush');
                $params = http_build_query($token->params());
                $destinationURL = 'index.php/' . ($this->checkModuleExists('cms') ? "home/successfullyinstalled?{$params}" : "?{$params}");
                echo <<<HTML
\t\t\t\t<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li>
\t\t\t\t<script>
\t\t\t\t\tsetTimeout(function() {
\t\t\t\t\t\twindow.location = "{$destinationURL}";
\t\t\t\t\t}, 2000);
\t\t\t\t</script>
\t\t\t\t<noscript>
\t\t\t\t<li><a href="{$destinationURL}">Click here to access your site.</a></li>
\t\t\t\t</noscript>
HTML;
            }
        }
        return $this->errors;
    }
    public function run($request)
    {
        // Extend time limit
        set_time_limit(100000);
        // we may need some proivileges for this to work
        // without this, running under sake is a problem
        // maybe sake could take care of it ...
        Security::findAnAdministrator()->login();
        $this->checkInstalled();
        $this->withTransaction(function ($task) {
            Versioned::reading_stage('Stage');
            $classes = $task->fluentClasses();
            $tables = DB::tableList();
            $deleteQueue = array();
            foreach ($classes as $class) {
                // Ensure that a translationgroup table exists for this class
                $groupTable = strtolower($class . "_translationgroups");
                if (isset($tables[$groupTable])) {
                    $groupTable = $tables[$groupTable];
                } else {
                    Debug::message("Ignoring class without _translationgroups table {$class}", false);
                    continue;
                }
                // Disable filter
                if ($class::has_extension('FluentFilteredExtension')) {
                    $class::remove_extension('FluentFilteredExtension');
                }
                // Select all instances of this class in the default locale
                $instances = DataObject::get($class, sprintf('"Locale" = \'%s\'', Convert::raw2sql(Fluent::default_locale())));
                foreach ($instances as $instance) {
                    $isPublished = false;
                    if ($instance->hasMethod('isPublished')) {
                        $isPublished = $instance->isPublished();
                    }
                    if ($instance->ObsoleteClassName) {
                        Debug::message("Skipping {$instance->ClassName} with ID {$instanceID} because it from an obsolete class", false);
                        continue;
                    }
                    $instanceID = $instance->ID;
                    $translatedFields = $task->getTranslatedFields($instance->ClassName);
                    Debug::message("Updating {$instance->ClassName} {$instance->MenuTitle} ({$instanceID})", false);
                    $changed = false;
                    // Select all translations for this
                    $translatedItems = DataObject::get($class, sprintf('"Locale" != \'%1$s\' AND "ID" IN (
							SELECT "OriginalID" FROM "%2$s" WHERE "TranslationGroupID" IN (
								SELECT "TranslationGroupID" FROM "%2$s" WHERE "OriginalID" = %3$d
							)
						)', Convert::raw2sql(Fluent::default_locale()), $groupTable, $instanceID));
                    foreach ($translatedItems as $translatedItem) {
                        $locale = DB::query(sprintf('SELECT "Locale" FROM "%s" WHERE "ID" = %d', $class, $translatedItem->ID))->value();
                        // since we are going to delete the stuff
                        // anyway, no need bothering validating it
                        DataObject::config()->validation_enabled = false;
                        // Unpublish and delete translated record
                        if ($translatedItem->hasMethod('doUnpublish')) {
                            Debug::message("  --  Unpublishing {$locale}", false);
                            if ($translatedItem->doUnpublish() === false) {
                                throw new ConvertTranslatableException("Failed to unpublish");
                            }
                        }
                        Debug::message("  --  Adding {$translatedItem->ID} ({$locale})", false);
                        foreach ($translatedFields as $field) {
                            $trField = Fluent::db_field_for_locale($field, $locale);
                            if ($translatedItem->{$field}) {
                                Debug::message("     --  Adding {$trField}", false);
                                $instance->{$trField} = $translatedItem->{$field};
                                $changed = true;
                            }
                        }
                        // for some reason, deleting items here has disruptive effects
                        // as too much stuff gets removed, so lets wait with this until the end of the migration
                        $deleteQueue[] = $translatedItem;
                    }
                    if ($changed) {
                        if (!$isPublished) {
                            $instance->write();
                        } elseif ($instance->doPublish() === false) {
                            Debug::message("  --  Publishing FAILED", false);
                            throw new ConvertTranslatableException("Failed to publish");
                        } else {
                            Debug::message("  --  Published", false);
                        }
                    }
                }
            }
            foreach ($deleteQueue as $delItem) {
                Debug::message("  --  Removing {$delItem->ID}", false);
                $delItem->delete();
            }
        });
    }
Пример #18
0
 function requireDefaultRecords()
 {
     parent::requireDefaultRecords();
     if (!DB::query("SELECT * FROM Member")->value() && isset($_REQUEST['username']) && isset($_REQUEST['password'])) {
         Security::findAnAdministrator($_REQUEST['username'], $_REQUEST['password']);
         Database::alteration_message("Added admin account", "created");
     }
 }
 /**
  * Method to authenticate an user
  *
  * @param array $RAW_data Raw data to authenticate the user
  * @param Form $form Optional: If passed, better error messages can be
  *                             produced by using
  *                             {@link Form::sessionMessage()}
  * @return bool|Member Returns FALSE if authentication fails, otherwise
  *                     the member object
  * @see Security::setDefaultAdmin()
  */
 public static function authenticate($RAW_data, Form $form = null)
 {
     if (array_key_exists('Email', $RAW_data) && $RAW_data['Email']) {
         $SQL_user = Convert::raw2sql($RAW_data['Email']);
     } else {
         return false;
     }
     $isLockedOut = false;
     $result = null;
     // Default login (see Security::setDefaultAdmin())
     if (Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) {
         $member = Security::findAnAdministrator();
     } else {
         $member = DataObject::get_one("Member", "\"" . Member::get_unique_identifier_field() . "\" = '{$SQL_user}' AND \"Password\" IS NOT NULL");
         if ($member) {
             $result = $member->checkPassword($RAW_data['Password']);
         } else {
             $result = new ValidationResult(false, _t('Member.ERRORWRONGCRED'));
         }
         if ($member && !$result->valid()) {
             $member->registerFailedLogin();
             $member = false;
         }
     }
     // Optionally record every login attempt as a {@link LoginAttempt} object
     /**
      * TODO We could handle this with an extension
      */
     if (Security::login_recording()) {
         $attempt = new LoginAttempt();
         if ($member) {
             // successful login (member is existing with matching password)
             $attempt->MemberID = $member->ID;
             $attempt->Status = 'Success';
             // Audit logging hook
             $member->extend('authenticated');
         } else {
             // failed login - we're trying to see if a user exists with this email (disregarding wrong passwords)
             $existingMember = DataObject::get_one("Member", "\"" . Member::get_unique_identifier_field() . "\" = '{$SQL_user}'");
             if ($existingMember) {
                 $attempt->MemberID = $existingMember->ID;
                 // Audit logging hook
                 $existingMember->extend('authenticationFailed');
             } else {
                 // Audit logging hook
                 singleton('Member')->extend('authenticationFailedUnknownUser', $RAW_data);
             }
             $attempt->Status = 'Failure';
         }
         if (is_array($RAW_data['Email'])) {
             user_error("Bad email passed to MemberAuthenticator::authenticate(): {$RAW_data['Email']}", E_USER_WARNING);
             return false;
         }
         $attempt->Email = $RAW_data['Email'];
         $attempt->IP = Controller::curr()->getRequest()->getIP();
         $attempt->write();
     }
     // Legacy migration to precision-safe password hashes.
     // A login-event with cleartext passwords is the only time
     // when we can rehash passwords to a different hashing algorithm,
     // bulk-migration doesn't work due to the nature of hashing.
     // See PasswordEncryptor_LegacyPHPHash class.
     if ($member && self::$migrate_legacy_hashes && array_key_exists($member->PasswordEncryption, self::$migrate_legacy_hashes)) {
         $member->Password = $RAW_data['Password'];
         $member->PasswordEncryption = self::$migrate_legacy_hashes[$member->PasswordEncryption];
         $member->write();
     }
     if ($member) {
         Session::clear('BackURL');
     } else {
         if ($form && $result) {
             $form->sessionMessage($result->message(), 'bad');
         }
     }
     return $member;
 }
Пример #20
0
	function install($config) {
?>
<html>
	<head>
		<title>Installing SilverStripe...</title>
		<link rel="stylesheet" type="text/css" href="<?php echo FRAMEWORK_NAME; ?>/dev/install/css/install.css" />
		<script src="<?php echo FRAMEWORK_NAME; ?>/thirdparty/jquery/jquery.js"></script>
	</head>
	<body>
		<div class="install-header">
			<div class="inner">
				<div class="brand">
					<span class="logo"></span>
					<h1>SilverStripe</h1>
				</div>
			</div>	
		</div>

		<div id="Navigation">&nbsp;</div>
		<div class="clear"><!-- --></div>

		<div class="main">
			<div class="inner">
				<h2>Installing SilverStripe...</h2>
				<p>I am now running through the installation steps (this should take about 30 seconds)</p>
				<p>If you receive a fatal error, refresh this page to continue the installation</p>
				<ul>
<?php

		$webserver = $this->findWebserver();
		$isIIS = $this->isIIS();
		$isApache = $this->isApache();

		flush();

		if(isset($config['stats'])) {
			if(file_exists(FRAMEWORK_NAME . '/silverstripe_version')) {
				$silverstripe_version = file_get_contents(FRAMEWORK_NAME . '/silverstripe_version');
			} else {
				$silverstripe_version = "unknown";
			}

			$phpVersion = urlencode(phpversion());
			$encWebserver = urlencode($webserver);
			$dbType = $config['db']['type'];

			// Try to determine the database version from the helper
			$databaseVersion = $config['db']['type'];
			$helper = $this->getDatabaseConfigurationHelper($dbType);
			if($helper && method_exists($helper, 'getDatabaseVersion')) {
				$databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($config['db'][$dbType]));
			}

			$url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe=$silverstripe_version&PHP=$phpVersion&Database=$databaseVersion&WebServer=$encWebserver";

			if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
				$url .= '&ID=' . $_SESSION['StatsID'];
			}

			@$_SESSION['StatsID'] = file_get_contents($url);
		}

		if(file_exists('mysite/_config.php')) {
			// Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly
			// differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them
			$fh = fopen('mysite/_config.php', 'wb');
			fclose($fh);
		}
		$theme = isset($_POST['template']) ? $_POST['template'] : 'simple';
		$locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US';
		$type = $config['db']['type'];
		$dbConfig = $config['db'][$type];
		if(!isset($dbConfig['path'])) $dbConfig['path'] = '';
		if(!$dbConfig) {
			echo "<p style=\"color: red\">Bad config submitted</p><pre>";
			print_r($config);
			echo "</pre>";
			die();
		}

		// Write the config file
		global $usingEnv;
		if($usingEnv) {

			$this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php...");
			$this->writeToFile("mysite/_config.php", <<<PHP
<?php

global \$project;
\$project = 'mysite';

global \$database;
\$database = '{$dbConfig['database']}';

require_once('conf/ConfigureFromEnv.php');

MySQLDatabase::set_connection_charset('utf8');

// Set the current theme. More themes can be downloaded from
// http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme');

// Set the site locale
i18n::set_locale('$locale');

// Enable nested URLs for this site (e.g. page/sub-page/)
if (class_exists('SiteTree')) SiteTree::enable_nested_urls();
PHP
			);

		} else {
			$this->statusMessage("Setting up 'mysite/_config.php'...");
			$escapedPassword = addslashes($dbConfig['password']);
			$this->writeToFile("mysite/_config.php", <<<PHP
<?php

global \$project;
\$project = 'mysite';

global \$databaseConfig;
\$databaseConfig = array(
	"type" => '{$type}',
	"server" => '{$dbConfig['server']}',
	"username" => '{$dbConfig['username']}',
	"password" => '{$escapedPassword}',
	"database" => '{$dbConfig['database']}',
	"path" => '{$dbConfig['path']}',
);

MySQLDatabase::set_connection_charset('utf8');

// Set the current theme. More themes can be downloaded from
// http://www.silverstripe.org/themes/
SSViewer::set_theme('$theme');

// Set the site locale
i18n::set_locale('$locale');

// Enable nested URLs for this site (e.g. page/sub-page/)
if (class_exists('SiteTree')) SiteTree::enable_nested_urls();
PHP
			);
		}

		if (!$this->checkModuleExists('cms')) {
			$this->writeToFile("mysite/code/RootURLController.php", <<<PHP
<?php

class RootURLController extends Controller {

	function index() {
		echo "<html>Your site is now set up. Start adding controllers to mysite to get started.</html>";
	}

}
PHP
			);
		}

		// Write the appropriate web server configuration file for rewriting support
		if($this->hasRewritingCapability()) {
			if($isApache) {
				$this->statusMessage("Setting up '.htaccess' file...");
				$this->createHtaccess();
			} elseif($isIIS) {
				$this->statusMessage("Setting up 'web.config' file...");
				$this->createWebConfig();
			}
		}

		// Load the SilverStripe runtime
		$_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/' . FRAMEWORK_NAME . '/main.php';
		chdir(FRAMEWORK_NAME);

		// Rebuild the manifest
		$_GET['flush'] = true;
		// Show errors as if you're in development mode
		$_SESSION['isDev'] = 1;

		$this->statusMessage("Building database schema...");

		require_once 'core/Core.php';

		// Build database
		$con = new Controller();
		$con->pushCurrent();

		global $databaseConfig;
		DB::connect($databaseConfig);

		$dbAdmin = new DatabaseAdmin();
		$dbAdmin->init();

		$dbAdmin->doBuild(true);

		// Create default administrator user and group in database
		// (not using Security::setDefaultAdmin())
		$adminMember = Security::findAnAdministrator();
		$adminMember->Email = $config['admin']['username'];
		$adminMember->Password = $config['admin']['password'];
		$adminMember->PasswordEncryption = Security::get_password_encryption_algorithm();

		try {
			$this->statusMessage('Creating default CMS admin account...');
			$adminMember->write();
		} catch(Exception $e) {
			$this->statusMessage(
				sprintf('Warning: Default CMS admin account could not be created (error: %s)', $e->getMessage())
			);
		}

		// Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
		// show a warning if there was a problem doing so
		try {
			$this->statusMessage('Creating initial filesystem assets...');
			Filesystem::sync();
		} catch(Exception $e) {
			$this->statusMessage(
				sprintf('Warning: Creating initial filesystem assets failed (error: %s)', $e->getMessage())
			);
		}

		$_SESSION['username'] = $config['admin']['username'];
		$_SESSION['password'] = $config['admin']['password'];

		if(!$this->errors) {
			if(isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
				$this->statusMessage("Checking that friendly URLs work...");
				$this->checkRewrite();
			} else {
				$destinationURL = 'index.php/' .
					($this->checkModuleExists('cms') ? 'home/successfullyinstalled?flush=1' : '?flush=1');

				echo <<<HTML
				<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li>
				<script>
					setTimeout(function() {
						window.location = "$destinationURL";
					}, 2000);
				</script>
				<noscript>
				<li><a href="$destinationURL">Click here to access your site.</li>
				</noscript>
HTML;
			}
		}

		return $this->errors;
	}
 /**
  * Run the task, and do the business
  *
  * @param SS_HTTPRequest $httpRequest 
  */
 function run($httpRequest)
 {
     require_once 'Zend/Log/Writer/Stream.php';
     SS_Log::add_writer(new Zend_Log_Writer_Stream('php://output'), SS_Log::NOTICE);
     $db = DB::getConn();
     if (method_exists($db, 'supportsLocks') && $db->supportsLocks() && !$db->getLock('ScheduledPublishing')) {
         $this->log('Publication has already been triggered by a different process');
         return;
     }
     Cookie::$report_errors = false;
     if (class_exists('Subsite')) {
         Subsite::$disable_subsite_filter = true;
     }
     if (class_exists('Subsite')) {
         Subsite::$disable_subsite_filter = true;
     }
     $this->log('Looking for changes that need to be published');
     $bt = defined('DB::USE_ANSI_SQL') ? "\"" : "`";
     $wfRequests = DataObject::get('WorkflowRequest', "{$bt}Status{$bt} = 'Scheduled' AND {$bt}EmbargoDate{$bt} <= '" . SS_Datetime::now()->getValue() . "'");
     $this->log(sprintf('Found %d pages', $wfRequests ? count($wfRequests) : 0));
     $admin = Security::findAnAdministrator();
     $admin->logIn();
     if (count($wfRequests)) {
         foreach ($wfRequests as $request) {
             // Use a try block to prevent one bad request
             // taking down the whole queue
             try {
                 $page = $request->Page();
                 $this->log(sprintf("Attempting to publish '%s' (URL: %s)", $page->Title, $page->AbsoluteLink()));
                 // We remove the embargo date and republish to trigger this.
                 $request->EmbargoDate = null;
                 $result = $request->publish('Page was embargoed. Automatically published.', WorkflowSystemMember::get(), false);
                 $this->log(sprintf("Published '%s' (URL: %s)", $page->Title, $page->AbsoluteLink()));
             } catch (Exception $e) {
                 // Log it?
                 $this->log(sprintf("Failed to publish '%s (URL: %s)", $page->Title, $page->AbsoluteLink()));
                 user_error("Error publishing change to Page ID " . $request->PageID . " - " . $request->Page()->Title . " Error: " . $e->getMessage(), E_USER_WARNING);
                 continue;
             }
         }
     }
     $this->log('Looking for live pages that need to be expired');
     $pagesToExpire = Versioned::get_by_stage('SiteTree', 'Live', "\"ExpiryDate\" <= '" . SS_Datetime::now()->getValue() . "'");
     $this->log(sprintf('Found %d pages', $pagesToExpire ? count($pagesToExpire) : 0));
     if (count($pagesToExpire)) {
         foreach ($pagesToExpire as $page) {
             // Use a try block to prevent one bad request
             // taking down the whole queue
             try {
                 $this->log(sprintf("Attempting to unpublish '%s' (URL: %s)", $page->Title, $page->AbsoluteLink()));
                 // Close any existing workflows
                 if ($wf = $page->openWorkflowRequest()) {
                     $this->log(sprintf("Closing '%s' workflow request for '%s'", $wf->Status, $page->Title));
                     $wf->deny('Page automatically expired. Removing from Live site.', $admin);
                 }
                 $page->ExpiryDate = null;
                 $page->write();
                 $page->doUnpublish();
                 $this->log(sprintf("Unpublished '%s' (URL: %s)", $page->Title, $page->AbsoluteLink()));
             } catch (Exception $e) {
                 $this->log(sprintf("Failed to unpublish '%s' (URL: %s)", $page->Title, $page->AbsoluteLink()));
                 user_error("Error unpublishing Page ID " . $page->ID . " - " . $page->Title . " Error: " . $e->getMessage(), E_USER_WARNING);
                 continue;
             }
         }
     }
     // We don't need to clear the lock on every potential exception,
     // as the closing of the DB connection will do that for us.
     if (method_exists($db, 'supportsLocks') && $db->supportsLocks()) {
         $db->releaseLock('ScheduledPublishing');
     }
 }
 /**
  * Vote for a particular post
  * 
  * @param DataObject $post 
  */
 public function vote(DataObject $post, $dir = 1)
 {
     $member = $this->securityContext->getMember();
     if ($member->VotesToGive <= 0) {
         $post->RemainingVotes = 0;
         return $post;
     }
     // we allow multiple votes - as many as the user has to give! unless
     // configured not to...
     $currentVote = null;
     if ($this->singleVotes) {
         $votes = $post->currentVotesByUser();
         if (count($votes)) {
             $currentVote = $votes[0];
         }
     }
     if (!$currentVote) {
         $currentVote = MicroPostVote::create();
         $currentVote->UserID = $member->ID;
         $currentVote->PostID = $post->ID;
     }
     $currentVote->Direction = $dir > 0 ? 1 : -1;
     $currentVote->write();
     $list = DataList::create('MicroPostVote');
     $upList = $list->filter(array('PostID' => $post->ID, 'Direction' => 1));
     $post->Up = $upList->count();
     $downList = $list->filter(array('PostID' => $post->ID, 'Direction' => -1));
     $post->Down = $downList->count();
     $owner = $post->Owner();
     if (!$post->OwnerID || !$owner || !$owner->exists()) {
         $owner = Security::findAnAdministrator();
     }
     // write the post as the owner, and calculate some changes for the author
     $this->transactionManager->run(function () use($post, $currentVote, $member) {
         $author = $post->Owner();
         if ($author && $author->exists() && $author->ID != $member->ID) {
             if ($currentVote->Direction > 0) {
                 $author->Up += 1;
             } else {
                 $author->Down += 1;
             }
             $author->write();
         }
         $post->write();
     }, $owner);
     $this->rewardMember($member, -1);
     $post->RemainingVotes = $member->VotesToGive;
     return $post;
 }
    function install($config)
    {
        if (isset($_SERVER['HTTP_HOST'])) {
            ?>
<html>
	<head>
		<title>Installing SilverStripe...</title>
		<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/layout.css" />
		<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/typography.css" />
		<link rel="stylesheet" type="text/css" href="themes/blackcandy/css/form.css" />
		<link rel="stylesheet" type="text/css" href="sapphire/dev/install/install.css" />
		<script src="sapphire/thirdparty/jquery/jquery.js"></script>
	</head>
	<body>
		<div id="BgContainer">
			<div id="Container">
				<div id="Header">
					<h1>SilverStripe CMS Installation</h1>
				</div>

				<div id="Navigation">&nbsp;</div>
				<div class="clear"><!-- --></div>

				<div id="Layout">
					<div class="typography">
						<h1>Installing SilverStripe...</h1>
						<p>I am now running through the installation steps (this should take about 30 seconds)</p>
						<p>If you receive a fatal error, refresh this page to continue the installation</p>
						<ul>
<?php 
        } else {
            echo "SILVERSTRIPE COMMAND-LINE INSTALLATION\n\n";
        }
        $webserver = $this->findWebserver();
        $isIIS = $this->isIIS();
        $isApache = $this->isApache();
        flush();
        if (isset($config['stats'])) {
            if (file_exists('sapphire/silverstripe_version')) {
                $sapphireVersionFile = file_get_contents('sapphire/silverstripe_version');
                if (strstr($sapphireVersionFile, "/sapphire/trunk")) {
                    $silverstripe_version = "trunk";
                } else {
                    preg_match("/sapphire\\/(?:(?:branches)|(?:tags))(?:\\/rc)?\\/([A-Za-z0-9._-]+)\\/silverstripe_version/", $sapphireVersionFile, $matches);
                    $silverstripe_version = $matches[1];
                }
            } else {
                $silverstripe_version = "unknown";
            }
            $phpVersion = urlencode(phpversion());
            $encWebserver = urlencode($webserver);
            $dbType = $config['db']['type'];
            // Try to determine the database version from the helper
            $databaseVersion = $config['db']['type'];
            $helper = $this->getDatabaseConfigurationHelper($dbType);
            if ($helper && method_exists($helper, 'getDatabaseVersion')) {
                $databaseVersion = urlencode($dbType . ': ' . $helper->getDatabaseVersion($config['db'][$dbType]));
            }
            $url = "http://ss2stat.silverstripe.com/Installation/add?SilverStripe={$silverstripe_version}&PHP={$phpVersion}&Database={$databaseVersion}&WebServer={$encWebserver}";
            if (isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
                $url .= '&ID=' . $_SESSION['StatsID'];
            }
            @($_SESSION['StatsID'] = file_get_contents($url));
        }
        if (file_exists('mysite/_config.php')) {
            // Truncate the contents of _config instead of deleting it - we can't re-create it because Windows handles permissions slightly
            // differently to UNIX based filesystems - it takes the permissions from the parent directory instead of retaining them
            $fh = fopen('mysite/_config.php', 'wb');
            fclose($fh);
        }
        $theme = isset($_POST['template']) ? $_POST['template'] : 'blackcandy';
        $locale = isset($_POST['locale']) ? $_POST['locale'] : 'en_US';
        $type = $config['db']['type'];
        $dbConfig = $config['db'][$type];
        if (!$dbConfig) {
            echo "<p style=\"color: red\">Bad config submitted</p><pre>";
            print_r($config);
            echo "</pre>";
            die;
        }
        // Write the config file
        global $usingEnv;
        if ($usingEnv) {
            $this->statusMessage("Setting up 'mysite/_config.php' for use with _ss_environment.php...");
            $this->writeToFile("mysite/_config.php", <<<PHP
<?php

global \$project;
\$project = 'mysite';

global \$database;
\$database = '{$dbConfig['database']}';

require_once('conf/ConfigureFromEnv.php');

MySQLDatabase::set_connection_charset('utf8');

// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('{$theme}');

// Set the site locale
i18n::set_locale('{$locale}');

// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
PHP
);
        } else {
            $this->statusMessage("Setting up 'mysite/_config.php'...");
            $escapedPassword = addslashes($dbConfig['password']);
            $this->writeToFile("mysite/_config.php", <<<PHP
<?php

global \$project;
\$project = 'mysite';

global \$databaseConfig;
\$databaseConfig = array(
\t"type" => '{$type}',
\t"server" => '{$dbConfig['server']}', 
\t"username" => '{$dbConfig['username']}', 
\t"password" => '{$escapedPassword}', 
\t"database" => '{$dbConfig['database']}',
\t"path" => '{$dbConfig['path']}',
);

// Sites running on the following servers will be
// run in development mode. See
// http://doc.silverstripe.org/doku.php?id=configuration
// for a description of what dev mode does.
Director::set_dev_servers(array(
\t'localhost',
\t'127.0.0.1'
));

MySQLDatabase::set_connection_charset('utf8');

// This line set's the current theme. More themes can be
// downloaded from http://www.silverstripe.org/themes/
SSViewer::set_theme('{$theme}');

// Set the site locale
i18n::set_locale('{$locale}');

// enable nested URLs for this site (e.g. page/sub-page/)
SiteTree::enable_nested_urls();
PHP
);
        }
        // Write the appropriate web server configuration file for rewriting support
        if ($this->hasRewritingCapability()) {
            if ($isApache) {
                $this->statusMessage("Setting up '.htaccess' file...");
                $this->createHtaccess();
            } elseif ($isIIS) {
                $this->statusMessage("Setting up 'web.config' file...");
                $this->createWebConfig();
            }
        }
        // Load the sapphire runtime
        $_SERVER['SCRIPT_FILENAME'] = dirname(realpath($_SERVER['SCRIPT_FILENAME'])) . '/sapphire/main.php';
        chdir('sapphire');
        // Rebuild the manifest
        $_GET['flush'] = true;
        // Show errors as if you're in development mode
        $_SESSION['isDev'] = 1;
        require_once 'core/Core.php';
        $this->statusMessage("Building database schema...");
        // Build database
        $con = new Controller();
        $con->pushCurrent();
        global $databaseConfig;
        DB::connect($databaseConfig);
        $dbAdmin = new DatabaseAdmin();
        $dbAdmin->init();
        $dbAdmin->doBuild(true);
        // Create default administrator user and group in database
        // (not using Security::setDefaultAdmin())
        $adminMember = Security::findAnAdministrator();
        $adminMember->Email = $config['admin']['username'];
        $adminMember->Password = $config['admin']['password'];
        $adminMember->PasswordEncryption = Security::get_password_encryption_algorithm();
        // @todo Exception thrown if database with admin already exists with same Email
        try {
            $adminMember->write();
        } catch (Exception $e) {
        }
        // Syncing filesystem (so /assets/Uploads is available instantly, see ticket #2266)
        Filesystem::sync();
        $_SESSION['username'] = $config['admin']['username'];
        $_SESSION['password'] = $config['admin']['password'];
        if (!$this->errors) {
            if (isset($_SERVER['HTTP_HOST']) && $this->hasRewritingCapability()) {
                $this->statusMessage("Checking that friendly URLs work...");
                $this->checkRewrite();
            } else {
                echo <<<HTML
\t\t\t\t<li>SilverStripe successfully installed; I am now redirecting you to your SilverStripe site...</li>
\t\t\t\t<script>
\t\t\t\t\tsetTimeout(function() {
\t\t\t\t\t\twindow.location = "index.php/home/successfullyinstalled?flush=1";
\t\t\t\t\t}, 2000);
\t\t\t\t</script>
\t\t\t\t<noscript>
\t\t\t\t<li><a href="index.php/home/successfullyinstalled?flush=1">Click here to access your site.</li>
\t\t\t\t</noscript>
HTML;
            }
        }
        return $this->errors;
    }