public function FormatConfiguration($Data)
 {
     $Old = $Data;
     $New = $Data['_New'];
     unset($Old['_New']);
     $Old = Gdn_Configuration::Format($Old);
     $New = Gdn_Configuration::Format($New);
     $Diffs = $this->FormatDiff($Old, $New, 'raw');
     $Result = array();
     foreach ($Diffs as $Diff) {
         if (is_array($Diff)) {
             if (!empty($Diff['del'])) {
                 $Result[] = '<del>' . implode("<br />\n", $Diff['del']) . '</del>';
             }
             if (!empty($Diff['ins'])) {
                 $Result[] = '<ins>' . implode("<br />\n", $Diff['ins']) . '</ins>';
             }
         }
     }
     $Result = implode("<br />\n", $Result);
     if ($Result) {
         return $Result;
     } else {
         return T('No Change');
     }
 }
 public function Configuration()
 {
     $this->Permission('Garden.Settings.Manage');
     $this->DeliveryMethod(DELIVERY_METHOD_JSON);
     $this->DeliveryType(DELIVERY_TYPE_DATA);
     $ConfigData = array('Title' => C('Garden.Title'), 'Domain' => C('Garden.Domain'), 'Cookie' => C('Garden.Cookie'), 'Theme' => C('Garden.Theme'), 'Analytics' => array('InstallationID' => C('Garden.InstallationID'), 'InstallationSecret' => C('Garden.InstallationSecret')));
     $Config = Gdn_Configuration::Format($ConfigData, array('FormatStyle' => 'Dotted', 'WrapPHP' => FALSE, 'SafePHP' => FALSE, 'Headings' => FALSE, 'ByLine' => FALSE));
     $Configuration = array();
     eval($Config);
     $this->SetData('Configuration', $Configuration);
     $this->Render();
 }
 public function Save()
 {
     if (!$this->Dirty) {
         return NULL;
     }
     $this->EventArguments['ConfigDirty'] =& $this->Dirty;
     $this->EventArguments['ConfigNoSave'] = FALSE;
     $this->EventArguments['ConfigType'] = $this->Type;
     $this->EventArguments['ConfigSource'] = $this->Source;
     $this->EventArguments['ConfigData'] = $this->Settings;
     $this->FireEvent('BeforeSave');
     if ($this->EventArguments['ConfigNoSave']) {
         $this->Dirty = FALSE;
         return TRUE;
     }
     // Check for and fire callback if one exists
     if ($this->Callback && is_callable($this->Callback)) {
         $CallbackOptions = array();
         if (!is_array($this->CallbackOptions)) {
             $this->CallbackOptions = array();
         }
         $CallbackOptions = array_merge($CallbackOptions, $this->CallbackOptions, array('ConfigDirty' => $this->Dirty, 'ConfigType' => $this->Type, 'ConfigSource' => $this->Source, 'ConfigData' => $this->Settings, 'SourceObject' => $this));
         $ConfigSaved = call_user_func($this->Callback, $CallbackOptions);
         if ($ConfigSaved) {
             $this->Dirty = FALSE;
             return TRUE;
         }
     }
     switch ($this->Type) {
         case 'file':
             if (empty($this->Source)) {
                 trigger_error(ErrorMessage('You must specify a file path to be saved.', 'Configuration', 'Save'), E_USER_ERROR);
             }
             $CheckWrite = $this->Source;
             if (!file_exists($CheckWrite)) {
                 $CheckWrite = dirname($CheckWrite);
             }
             if (!is_writable($CheckWrite)) {
                 throw new Exception(sprintf(T("Unable to write to config file '%s' when saving."), $this->Source));
             }
             $Group = $this->Group;
             $Data =& $this->Settings;
             ksort($Data);
             // Check for the case when the configuration is the group.
             if (is_array($Data) && count($Data) == 1 && array_key_exists($Group, $Data)) {
                 $Data = $Data[$Group];
             }
             // Do a sanity check on the config save.
             if ($this->Source == Gdn::Config()->DefaultPath()) {
                 // Log root config changes
                 try {
                     $LogData = $this->Initial;
                     $LogData['_New'] = $this->Settings;
                     LogModel::Insert('Edit', 'Configuration', $LogData);
                 } catch (Exception $Ex) {
                 }
                 if (!isset($Data['Database'])) {
                     if ($Pm = Gdn::PluginManager()) {
                         $Pm->EventArguments['Data'] = $Data;
                         $Pm->EventArguments['Backtrace'] = debug_backtrace();
                         $Pm->FireEvent('ConfigError');
                     }
                     return FALSE;
                 }
             }
             // Write config data to string format, ready for saving
             $FileContents = Gdn_Configuration::Format($Data, array('VariableName' => $Group, 'WrapPHP' => TRUE, 'ByLine' => TRUE));
             if ($FileContents === FALSE) {
                 trigger_error(ErrorMessage('Failed to define configuration file contents.', 'Configuration', 'Save'), E_USER_ERROR);
             }
             // Save to cache if we're into that sort of thing
             $FileKey = sprintf(Gdn_Configuration::CONFIG_FILE_CACHE_KEY, $this->Source);
             if ($this->Configuration && $this->Configuration->Caching() && Gdn::Cache()->Type() == Gdn_Cache::CACHE_TYPE_MEMORY && Gdn::Cache()->ActiveEnabled()) {
                 $CachedConfigData = Gdn::Cache()->Store($FileKey, $Data, array(Gdn_Cache::FEATURE_NOPREFIX => TRUE, Gdn_Cache::FEATURE_EXPIRY => 3600));
             }
             $TmpFile = tempnam(PATH_CONF, 'config');
             $Result = FALSE;
             if (file_put_contents($TmpFile, $FileContents) !== FALSE) {
                 chmod($TmpFile, 0775);
                 $Result = rename($TmpFile, $this->Source);
             }
             if ($Result && function_exists('apc_delete_file')) {
                 // This fixes a bug with some configurations of apc.
                 @apc_delete_file($this->Source);
             }
             $this->Dirty = FALSE;
             return $Result;
             break;
         case 'json':
         case 'array':
         case 'string':
             /**
              * How would these even save? String config data must be handled by
              * an event hook or callback, if at all.
              */
             $this->Dirty = FALSE;
             return FALSE;
             break;
     }
 }