/**
  * Adds the default languages if they are missing
  */
 public function requireDefaultRecords()
 {
     parent::requireDefaultRecords();
     $defaultLangs = array_keys($this->defaultLanguages);
     $dbLangCount = SnippetLanguage::get()->filter('Name', $defaultLangs)->filter('UserLanguage', 0)->Count();
     if ($dbLangCount < count($defaultLangs)) {
         foreach ($this->defaultLanguages as $name => $data) {
             if (!SnippetLanguage::get()->find('Name', $name)) {
                 $lang = new SnippetLanguage();
                 $lang->Name = $name;
                 $lang->FileExtension = $data['Extension'];
                 $lang->HighlightCode = $data['HighlightCode'];
                 $lang->UserLanguage = false;
                 $lang->write();
                 DB::alteration_message('Created snippet language "' . $name . '"', 'created');
             }
         }
     }
     //Look for config languages
     $configLanguages = CodeBank::config()->extra_languages;
     if (!empty($configLanguages)) {
         foreach ($configLanguages as $language) {
             //Validate languages
             if (empty($language['Name']) || empty($language['FileName']) || empty($language['HighlightCode']) || empty($language['Brush'])) {
                 user_error('Invalid snippet user language found in config, user languages defined in config must contain a Name, FileName, HighlightCode and Brush file path', E_USER_WARNING);
                 continue;
             }
             $lang = SnippetLanguage::get()->filter('Name', Convert::raw2sql($language['Name']))->filter('HighlightCode', Convert::raw2sql($language['HighlightCode']))->filter('UserLanguage', true)->first();
             if (empty($lang) || $lang === false || $lang->ID <= 0) {
                 if (Director::is_absolute($language['Brush']) || Director::is_absolute_url($language['Brush'])) {
                     user_error('Invalid snippet user language found in config, user languages defined in config must contain a path to the brush relative to the SilverStripe base (' . Director::baseFolder() . ')', E_USER_WARNING);
                     continue;
                 }
                 if (preg_match('/\\.js$/', $language['Brush']) == 0) {
                     user_error('Invalid snippet user language found in config, user languages defined in config must be javascript files', E_USER_WARNING);
                     continue;
                 }
                 //Add language
                 $lang = new SnippetLanguage();
                 $lang->Name = $language['Name'];
                 $lang->FileExtension = $language['FileName'];
                 $lang->HighlightCode = $language['HighlightCode'];
                 $lang->BrushFile = $language['Brush'];
                 $lang->UserLanguage = true;
                 $lang->write();
                 DB::alteration_message('Created snippet user language "' . $language['Name'] . '"', 'created');
             }
         }
     }
 }
Example #2
0
 public function save($con = null)
 {
     $highlighted = myUtils::highlight($this->getRawBody());
     $this->setBody($highlighted['body']);
     foreach ($this->getSnippetLanguages() as $language) {
         $language->delete();
     }
     foreach ($highlighted['langs'] as $lang => $count) {
         $sl = new SnippetLanguage();
         $sl->setName($lang);
         $sl->setSnippet($this);
         $this->addSnippetLanguage($sl);
     }
     $summarizer = new Summarizer(400);
     $this->setSummary($summarizer->summarize($this->getBody()));
     parent::save();
 }
 /**
  * @return Array Map of Snippet Language IDs
  */
 public function snippetLanguagesIncluded()
 {
     if ($this->_cache_snippet_ids === null) {
         $this->populateSnippetIDs();
     }
     if (empty($this->_cache_snippet_ids)) {
         return array();
     }
     $q = SnippetLanguage::get()->innerJoin('Snippet', '"Snippet"."LanguageID"="SnippetLanguage"."ID"');
     if (isset($this->params['LanguageID']) && !empty($this->params['LanguageID'])) {
         $q = $q->filter('ID', intval($this->params['LanguageID']));
     }
     $q = $q->filter('Snippets.ID', array_keys($this->_cache_snippet_ids));
     return $q->column('ID');
 }
 /**
  * Returns the form field - used by templates. Although FieldHolder is generally what is inserted into templates, all of the field holder templates make use of $Field.  It's expected that FieldHolder will give you the "complete" representation of the field on the form, whereas Field will give you the core editing widget, such as an input tag.
  * @param {array} $properties key value pairs of template variables
  * @return {string} Returns the html to be sent to the browser
  */
 public function Field($properties = array())
 {
     $obj = $properties ? $this->customise($properties) : $this;
     Requirements::css(CB_DIR . '/javascript/external/syntaxhighlighter/themes/shCore.css');
     Requirements::css(CB_DIR . '/javascript/external/syntaxhighlighter/themes/shCore' . $this->theme_file() . '.css');
     Requirements::css(CB_DIR . '/javascript/external/syntaxhighlighter/themes/shTheme' . $this->theme_file() . '.css');
     Requirements::css(CB_DIR . '/css/HighlightedContentField.css');
     Requirements::javascript(CB_DIR . '/javascript/external/syntaxhighlighter/brushes/shCore.js');
     $brushName = $this->getBrushName();
     if (!empty($brushName)) {
         Requirements::javascript(CB_DIR . '/javascript/external/syntaxhighlighter/brushes/' . $this->getBrushName() . '.js');
     } else {
         $lang = SnippetLanguage::get()->filter('HighlightCode', Convert::raw2sql($this->language))->filter('UserLanguage', true)->first();
         if (!empty($lang) && $lang !== false && $lang->ID > 0 && !empty($lang->BrushFile)) {
             Requirements::javascript($lang->BrushFile);
         }
     }
     Requirements::javascript(CB_DIR . '/javascript/HighlightedContentField.js');
     return $obj->renderWith('HighlightedContentField');
 }
 /**
  * Saves a new folder
  * @param {stdClass} $data Data passed from ActionScript
  * @return {array} Standard response base
  */
 public function newFolder($data)
 {
     $response = CodeBank_ClientAPI::responseBase();
     //Ensure logged in
     if (!Permission::check('CODE_BANK_ACCESS')) {
         $response['status'] = 'EROR';
         $response['message'] = _t('CodeBankAPI.PERMISSION_DENINED', '_Permission Denied');
         return $response;
     }
     $language = SnippetLanguage::get()->byID(intval($data->languageID));
     if (empty($language) || $language === false || $language->ID == 0) {
         $response['status'] = "EROR";
         $response['message'] = _t('CodeBankAPI.LANGUAGE_NOT_FOUND', '_Language not found');
         return $response;
     }
     if ($data->parentID > 0) {
         $folder = SnippetFolder::get()->byID(intval($data->parentID));
         if (empty($folder) || $folder === false || $folder->ID == 0) {
             $response['status'] = "EROR";
             $response['message'] = _t('CodeBankAPI.FOLDER_DOES_NOT_EXIST', '_Folder does not exist');
             return $response;
         }
         if ($folder->LanguageID != $language->ID) {
             $response['status'] = "EROR";
             $response['message'] = _t('CodeBankAPI.FOLDER_NOT_LANGUAGE', '_Folder is not in the same language as the snippet');
             return $response;
         }
     }
     //Check existing
     $existingCheck = SnippetFolder::get()->filter('Name:nocase', Convert::raw2sql($data->name))->filter('LanguageID', $language->ID)->filter('ParentID', $data->parentID);
     if ($existingCheck->Count() > 0) {
         $response['status'] = "EROR";
         $response['message'] = _t('CodeBank.FOLDER_EXISTS', '_A folder already exists with that name');
         return $response;
     }
     try {
         $snippetFolder = new SnippetFolder();
         $snippetFolder->Name = $data->name;
         $snippetFolder->LanguageID = $data->languageID;
         $snippetFolder->ParentID = $data->parentID;
         $snippetFolder->write();
         $response['status'] = "HELO";
     } catch (Exception $e) {
         $response['status'] = "EROR";
         $response['message'] = "Internal Server error occured";
     }
     return $response;
 }
 /**
  * Handles moving of a snippet when the tree is reordered
  * @param {SS_HTTPRequest} $request HTTP Request
  */
 public function moveSnippet(SS_HTTPRequest $request)
 {
     $snippet = Snippet::get()->byID(intval($request->getVar('ID')));
     if (empty($snippet) || $snippet === false || $snippet->ID == 0) {
         $this->response->setStatusCode(403, _t('CodeBank.SNIPPIT_NOT_EXIST', '_Snippit does not exist'));
         return;
     }
     $parentID = $request->getVar('ParentID');
     if (strpos($parentID, 'language-') !== false) {
         $lang = SnippetLanguage::get()->byID(intval(str_replace('language-', '', $parentID)));
         if (empty($lang) || $lang === false || $lang->ID == 0) {
             $this->response->setStatusCode(403, _t('CodeBank.LANGUAGE_NOT_EXIST', '_Language does not exist'));
             return;
         }
         if ($lang->ID != $snippet->LanguageID) {
             $this->response->setStatusCode(403, _t('CodeBank.CANNOT_MOVE_TO_LANGUAGE', '_You cannot move a snippet to another language'));
             return;
         }
         //Move out of folder
         DB::query('UPDATE "Snippet" SET "FolderID"=0 WHERE "ID"=' . $snippet->ID);
         $this->response->addHeader('X-Status', rawurlencode(_t('CodeBank.SNIPPET_MOVED', '_Snippet moved successfully')));
         return;
     } else {
         if (strpos($parentID, 'folder-') !== false) {
             $folder = SnippetFolder::get()->byID(intval(str_replace('folder-', '', $parentID)));
             if (empty($folder) || $folder === false || $folder->ID == 0) {
                 $this->response->setStatusCode(403, _t('CodeBank.FOLDER_NOT_EXIST', '_Folder does not exist'));
                 return;
             }
             if ($folder->LanguageID != $snippet->LanguageID) {
                 $this->response->setStatusCode(403, _t('CodeBank.CANNOT_MOVE_TO_FOLDER', '_You cannot move a snippet to a folder in another language'));
                 return;
             }
             //Move to folder
             DB::query('UPDATE "Snippet" SET "FolderID"=' . $folder->ID . ' WHERE "ID"=' . $snippet->ID);
             $this->response->addHeader('X-Status', rawurlencode(_t('CodeBank.SNIPPET_MOVED', '_Snippet moved successfully')));
             return;
         }
     }
     $this->response->setStatusCode(403, _t('CodeBank.UNKNOWN_PARENT', '_Unknown Parent'));
 }
 /**
  * Edits a language
  * @param {stdClass} $data Data passed from ActionScript
  * @return {array} Returns a standard response array
  */
 public function editLanguage($data)
 {
     $response = CodeBank_ClientAPI::responseBase();
     try {
         if (SnippetLanguage::get()->filter('Name:nocase', Convert::raw2sql($data->language))->Count() > 0) {
             $response['status'] = 'EROR';
             $response['message'] = _t('CodeBankAPI.LANGUAGE_EXISTS', '_Language already exists');
             return $response;
         }
         $lang = SnippetLanguage::get()->byID(intval($data->id));
         if (empty($lang) || $lang === false || $lang->ID == 0) {
             $response['status'] = 'EROR';
             $response['message'] = _t('CodeBankAPI.LANGUAGE_NOT_FOUND', '_Language not found');
             return $response;
         }
         //Update language and write
         if ($lang->UserLanguage == true) {
             $lang->Name = $data->language;
             $lang->FileExtension = $data->fileExtension;
         }
         $lang->Hidden = $data->hidden;
         $lang->write();
         $response['status'] = 'HELO';
         $response['message'] = "Language edited successfully";
     } catch (Exception $e) {
         $response['status'] = 'EROR';
         $response['message'] = _t('CodeBankAPI.SERVER_ERROR', '_Server error has occured, please try again later');
     }
     return $response;
 }
 /**
  * Gets fields used in the cms
  * @return {FieldList} Fields to be used
  */
 public function getCMSFields()
 {
     $langGridConfig = GridFieldConfig_RecordEditor::create(30);
     $langGridConfig->getComponentByType('GridFieldDetailForm')->setItemRequestClass('CodeBankGridField_ItemRequest');
     $langGridConfig->getComponentByType('GridFieldDataColumns')->setFieldCasting(array('UserLanguage' => 'Boolean->Nice', 'Hidden' => 'Boolean->Nice'));
     $packageGridConfig = GridFieldConfig_RecordEditor::create(30);
     $packageGridConfig->addComponent(new ExportPackageButton());
     $packageGridConfig->getComponentByType('GridFieldDetailForm')->setItemRequestClass('CodeBankGridField_ItemRequest')->setItemEditFormCallback(function (Form $form, GridFieldDetailForm_ItemRequest $itemRequest) {
         Requirements::javascript(CB_DIR . '/javascript/SnippetPackages.ItemEditForm.js');
         if ($form->getRecord() && $form->getRecord()->ID > 0) {
             $form->Actions()->push(FormAction::create('doExportPackage', _t('CodeBank.EXPORT', '_Export'))->setForm($form));
         }
         $form->addExtraClass('CodeBankPackages');
     });
     if (Permission::check('ADMIN')) {
         $fields = new FieldList(new TabSet('Root', new Tab('Main', _t('CodeBankConfig.MAIN', '_IP Message'), HtmlEditorField::create('IPMessage', _t('CodeBankConfig.IP_MESSAGE', '_Intellectual Property Message'))->addExtraClass('stacked')), new Tab('Languages', _t('CodeBankConfig.LANGUAGES', '_Languages'), new GridField('Languages', _t('CodeBankConfig.LANGUAGES', '_Languages'), SnippetLanguage::get(), $langGridConfig)), new Tab('Packages', _t('CodeBank.PACKAGES', '_Packages'), new GridField('Packages', _t('CodeBankConfig.MANAGE_PACKAGES', '_Manage Packages'), SnippetPackage::get(), $packageGridConfig))));
     } else {
         $fields = new FieldList(new TabSet('Root', new Tab('Packages', _t('CodeBank.PACKAGES', '_Packages'), new GridField('Packages', _t('CodeBankConfig.MANAGE_PACKAGES', '_Manage Packages'), SnippetPackage::get(), $packageGridConfig))));
     }
     return $fields;
 }
 /**
  * Return children from the stage site
  *
  * @param showAll Inlcude all of the elements, even those not shown in the menus.
  *   (only applicable when extension is applied to {@link SiteTree}).
  * @return SS_List
  */
 public function stageChildren($showAll = false)
 {
     $baseClass = ClassInfo::baseDataClass($this->owner->class);
     if ($baseClass == 'SnippetPackage') {
         if ($this->owner->ID == 0) {
             $staged = SnippetPackage::get();
         }
     } else {
         if ($baseClass == 'SnippetLanguage') {
             if ($this->owner->ID == 0) {
                 $staged = SnippetLanguage::get();
             } else {
                 $staged = ArrayList::create(array_merge($this->owner->Folders()->toArray(), $this->owner->Snippets()->filter('FolderID', 0)->toArray()));
             }
         } else {
             if ($baseClass == 'SnippetFolder') {
                 $staged = ArrayList::create(array_merge($this->owner->Folders()->toArray(), $this->owner->Snippets()->toArray()));
             } else {
                 $staged = new ArrayList();
             }
         }
     }
     $this->owner->extend("augmentStageChildren", $staged, $showAll);
     return $staged;
 }
 /**
  * Tests creating a folder, as well as checks to see that the duplicate detection is working and that detection for different languages is also working
  */
 public function testCreatingFolder()
 {
     $this->objFromFixture('Member', 'apiuser')->login();
     $languageID = SnippetLanguage::get()->filter('Name', 'CSS')->first()->ID;
     //Test creating a folder
     $response = $this->getAMFResponse('Snippets.newFolder', array('name' => 'API Folder', 'languageID' => $languageID, 'parentID' => 0));
     //Validate the response
     print $response['message'];
     $this->assertEquals('HELO', $response['status'], 'Response status should have been HELO');
     //Test creating a duplicate folder
     $response = $this->getAMFResponse('Snippets.newFolder', array('name' => 'API Folder', 'languageID' => $languageID, 'parentID' => 0));
     //Validate the response
     $this->assertEquals('EROR', $response['status'], 'Response status should have been EROR');
     $this->assertEquals(_t('CodeBank.FOLDER_EXISTS', '_A folder already exists with that name'), $response['message'], 'Response message should have been that there is a duplicate');
     //Test creating a folder under a different language
     $response = $this->getAMFResponse('Snippets.newFolder', array('name' => 'API Folder 2', 'languageID' => $languageID, 'parentID' => $this->objFromFixture('SnippetFolder', 'folder1')->ID));
     //Validate the response
     $this->assertEquals('EROR', $response['status'], 'Response status should have been EROR');
     $this->assertEquals(_t('CodeBankAPI.FOLDER_NOT_LANGUAGE', '_Folder is not in the same language as the snippet'), $response['message'], 'Response message should have been that the parent folder is in a different language');
 }
 /**
  * Processes the upload request
  * @param {array} $data Submitted data
  * @param {Form} $form Submitting form
  * @return {SS_HTTPResponse} Response
  */
 public function doImportData($data, Form $form)
 {
     if (!Permission::check('ADMIN')) {
         Security::permissionFailure($this);
         return;
     }
     $fileData = $form->Fields()->dataFieldByName('ImportFile')->Value();
     //Check that the file uploaded
     if (!array_key_exists('tmp_name', $fileData) || !file_exists($fileData['tmp_name'])) {
         $form->sessionMessage(_t('CodeBank.IMPORT_READ_ERROR', '_Could not read the file to be imported'), 'bad');
         return $this->redirectBack();
     }
     //Load the file into memory
     $fileData = file_get_contents($fileData['tmp_name']);
     if ($fileData === false || empty($fileData)) {
         $form->sessionMessage(_t('CodeBank.IMPORT_READ_ERROR', '_Could not read the file to be imported'), 'bad');
         return $this->redirectBack();
     }
     //Decode the json
     $fileData = json_decode($fileData);
     if ($fileData === false || !is_object($fileData)) {
         $form->sessionMessage(_t('CodeBank.IMPORT_READ_ERROR', '_Could not read the file to be imported'), 'bad');
         return $this->redirectBack();
     }
     //Verify the format is ToServer
     if ($fileData->format != 'ToServer') {
         $form->sessionMessage(_t('CodeBank.IMPORT_FILE_FORMAT_INCORRECT', '_Import file format is incorrect'), 'bad');
         return $this->redirectBack();
     }
     //Bump Up the time limit this may take time
     set_time_limit(480);
     //Start transaction if supported
     if (DB::getConn()->supportsTransactions()) {
         DB::getConn()->transactionStart();
     }
     //If not appending empty the tables
     if (!isset($data['AppendData'])) {
         DB::query('DELETE FROM Snippet');
         DB::query('DELETE FROM SnippetVersion');
         DB::query('DELETE FROM SnippetLanguage');
         DB::query('DELETE FROM SnippetPackage');
         DB::query('DELETE FROM SnippetFolder');
     } else {
         $langMap = array();
         $pkgMap = array();
         $folderMap = array();
         $snipMap = array();
     }
     //Import Languages
     foreach ($fileData->data->languages as $lang) {
         if (isset($data['AppendData'])) {
             $dbLang = SnippetLanguage::get()->filter('Name:ExactMatch:nocase', Convert::raw2sql($lang->language))->first();
             if (!empty($dbLang) && $dbLang !== false && $dbLang->ID > 0) {
                 $langMap['lang-' . $lang->id] = $dbLang->ID;
             } else {
                 $newLang = new SnippetLanguage();
                 $newLang->Name = $lang->language;
                 $newLang->FileExtension = $lang->file_extension;
                 $newLang->HighlightCode = $lang->shjs_code;
                 $newLang->UserLanguage = $lang->user_language;
                 $newLang->write();
                 $langMap['lang-' . $lang->id] = $newLang->ID;
                 unset($newLang);
             }
         } else {
             DB::query('INSERT INTO "SnippetLanguage" ("ID", "ClassName", "Created", "LastEdited", "Name", "FileExtension", "HighlightCode", "UserLanguage") ' . "VALUES(" . intval($lang->id) . ",'SnippetLanguage', '" . date('Y-m-d H:i:s') . "','" . date('Y-m-d H:i:s') . "','" . Convert::raw2sql($lang->language) . "','" . Convert::raw2sql($lang->file_extension) . "','" . Convert::raw2sql($lang->shjs_code) . "'," . intval($lang->user_language) . ")");
         }
     }
     //Import Packages
     foreach ($fileData->data->packages as $pkg) {
         if (isset($data['AppendData'])) {
             $newPkg = new SnippetPackage();
             $newPkg->Title = $pkg->title;
             $newPkg->write();
             $pkgMap['pkg-' . $pkg->id] = $newPkg->ID;
             unset($newPkg);
         } else {
             DB::query('INSERT INTO "SnippetPackage" ("ID", "ClassName", "Created", "LastEdited", "Title") ' . "VALUES(" . intval($pkg->id) . ",'SnippetPackage', '" . date('Y-m-d H:i:s') . "','" . date('Y-m-d H:i:s') . "','" . Convert::raw2sql($pkg->title) . "')");
         }
     }
     //Import Folders
     foreach ($fileData->data->folders as $folder) {
         if (isset($data['AppendData'])) {
             if (!isset($langMap['lang-' . $folder->fkLanguageId])) {
                 if (DB::getConn()->supportsTransactions()) {
                     DB::getConn()->transactionRollback();
                 }
                 $form->sessionMessage(_t('CodeBank.IMPORT_LANG_NOT_FOUND', '_Import failed language not found'), 'bad');
                 return $this->redirectBack();
             }
             $newFld = new SnippetFolder();
             $newFld->Name = $folder->name;
             $newFld->ParentID = $folder->fkParentId > 0 && isset($folderMap['fld-' . $folder->fkParentId]) ? $folderMap['fld-' . $folder->fkParentId] : 0;
             $newFld->LanguageID = $langMap['lang-' . $folder->fkLanguageId];
             $newFld->write();
             $folderMap['fld-' . $folder->id] = $newFld->ID;
             unset($newFld);
         } else {
             DB::query('INSERT INTO "SnippetFolder" ("ID", "ClassName", "Created", "LastEdited", "Name", "ParentID", "LanguageID") ' . "VALUES(" . intval($folder->id) . ",'SnippetFolder', '" . date('Y-m-d H:i:s') . "','" . date('Y-m-d H:i:s') . "','" . Convert::raw2sql($folder->name) . "', " . intval($folder->fkParentId) . ", " . intval($folder->fkLanguageId) . ")");
         }
     }
     //Import Snippets
     foreach ($fileData->data->snippets as $snip) {
         if (isset($data['AppendData'])) {
             if (!isset($langMap['lang-' . $snip->fkLanguage])) {
                 if (DB::getConn()->supportsTransactions()) {
                     DB::getConn()->transactionRollback();
                 }
                 $form->sessionMessage(_t('CodeBank.IMPORT_LANG_NOT_FOUND', '_Import failed language not found'), 'bad');
                 return $this->redirectBack();
             }
             $newSnip = new Snippet();
             $newSnip->Title = $snip->title;
             $newSnip->Description = $snip->description;
             $newSnip->Tags = $snip->tags;
             $newSnip->LanguageID = $langMap['lang-' . $snip->fkLanguage];
             $newSnip->CreatorID = Member::currentUserID();
             $newSnip->LastEditorID = Member::currentUserID();
             $newSnip->PackageID = $snip->fkPackageID > 0 && isset($pkgMap['pkg-' . $snip->fkPackageID]) ? $pkgMap['pkg-' . $snip->fkPackageID] : 0;
             $newSnip->FolderID = $snip->fkFolderID > 0 && isset($folderMap['fld-' . $snip->fkFolderID]) ? $folderMap['fld-' . $snip->fkFolderID] : 0;
             $newSnip->write();
             $snipMap['snip-' . $snip->id] = $newSnip->ID;
             unset($newSnip);
         } else {
             DB::query('INSERT INTO "Snippet" ("ID", "ClassName", "Created", "LastEdited", "Title", "Description", "Tags", "LanguageID", "CreatorID", "LastEditorID", "PackageID", "FolderID") ' . "VALUES(" . intval($snip->id) . ",'Snippet', '" . date('Y-m-d H:i:s') . "','" . date('Y-m-d H:i:s') . "','" . Convert::raw2sql($snip->title) . "', '" . Convert::raw2sql($snip->description) . "', '" . Convert::raw2sql($snip->tags) . "', " . intval($snip->fkLanguage) . ", " . Member::currentUserID() . ", " . Member::currentUserID() . ", " . intval($snip->fkPackageID) . ", " . intval($snip->fkFolderID) . ")");
         }
     }
     //Import Snippet Versions
     foreach ($fileData->data->versions as $ver) {
         if (isset($data['AppendData'])) {
             if (!isset($snipMap['snip-' . $ver->fkSnippit])) {
                 if (DB::getConn()->supportsTransactions()) {
                     DB::getConn()->transactionRollback();
                 }
                 $form->sessionMessage(_t('CodeBank.IMPORT_SNIP_NOT_FOUND', '_Import failed snippet not found'), 'bad');
                 return $this->redirectBack();
             }
             DB::query('INSERT INTO "SnippetVersion" ("ClassName", "Created", "LastEdited", "Text", "ParentID") ' . "VALUES('SnippetVersion', '" . Convert::raw2sql($ver->date) . "','" . Convert::raw2sql($ver->date) . "','" . Convert::raw2sql($ver->text) . "', " . intval($snipMap['snip-' . $ver->fkSnippit]) . ")");
         } else {
             DB::query('INSERT INTO "SnippetVersion" ("ID", "ClassName", "Created", "LastEdited", "Text", "ParentID") ' . "VALUES(" . intval($ver->id) . ",'SnippetVersion', '" . Convert::raw2sql($ver->date) . "','" . Convert::raw2sql($ver->date) . "','" . Convert::raw2sql($ver->text) . "', " . intval($ver->fkSnippit) . ")");
         }
     }
     //End transaction if supported
     if (DB::getConn()->supportsTransactions()) {
         DB::getConn()->transactionEnd();
     }
     //Display success after redirecting back
     Session::set('reloadOnImportDialogClose', true);
     $form->sessionMessage(_t('CodeBank.IMPORT_COMPLETE', '_Import Completed'), 'good');
     return $this->redirectBack();
 }
 /**
  * Performs the migration
  */
 public function run($request)
 {
     //Check for tables
     $tables = DB::tableList();
     if (!array_key_exists('languages', $tables) || !array_key_exists('snippits', $tables) || !array_key_exists('snippit_history', $tables) || !array_key_exists('preferences', $tables) || !array_key_exists('settings', $tables) || !array_key_exists('snippit_search', $tables) || !array_key_exists('users', $tables)) {
         echo '<b>' . _t('CodeBankLegacyMigrate.TABLES_NOT_FOUND', '_Could not find Code Bank 2.2 database tables, cannot migrate') . '</b>';
         exit;
     }
     //Ensure Empty
     if (Snippet::get()->Count() > 0) {
         echo '<b>' . _t('CodeBankLegacyMigrate.SNIPPETS_PRESENT', '_Already appears to be snippets present in the database, please start with a clean database, cannot migrate.') . '</b>';
         exit;
     }
     //Increase Timeout, since 30s probably won't be enough in huge databases
     increase_time_limit_to(600);
     //Find Other language
     $plainTextID = SnippetLanguage::get()->filter('Name', 'Other')->first();
     if (empty($plainTextID) || $plainTextID == false || $plainTextID->ID == 0) {
         echo _t('CodeBankLegacyMigrate.OTHER_NOT_FOUND', '_Could not find the Other Language, cannot migrate, please run dev/build first');
         exit;
     } else {
         $plainTextID = $plainTextID->ID;
     }
     //Check for users group
     $usersGroup = Group::get()->filter('Code', 'code-bank-api')->first();
     if (empty($usersGroup) || $usersGroup == false || $usersGroup->ID == 0) {
         //Rollback Transaction
         if (DB::getConn()->supportsTransactions()) {
             DB::getConn()->transactionRollback();
         }
         echo _t('CodeBankLegacyMigrate.GROUP_NOT_FOUND', '_Could not find users group, cannot migrate, please run dev/build first');
         exit;
     }
     //Start Transaction
     if (DB::getConn()->supportsTransactions()) {
         DB::getConn()->transactionStart();
     }
     //Migrate Languages
     echo '<b>' . _t('CodeBankLegacyMigrate.MIGRATE_USER_LANGUAGES', '_Migrating User Languages') . '</b>... ';
     $results = DB::query('SELECT * FROM "languages" WHERE "user_language"=1');
     if ($results->numRecords() > 0) {
         foreach ($results as $row) {
             DB::query('INSERT INTO "SnippetLanguage" ("ClassName","Created", "LastEdited", "Name", "FileExtension", "HighlightCode", "UserLanguage") ' . "VALUES('SnippetLanguage','" . date('Y-m-d H:i:s') . "','" . date('Y-m-d H:i:s') . "','" . Convert::raw2sql($row['language']) . "','" . Convert::raw2sql($row['file_extension']) . "','" . Convert::raw2sql($row['sjhs_code']) . "',1)");
         }
         echo _t('CodeBankLegacyMigrate.DONE', '_Done') . '<br/>';
     } else {
         echo _t('CodeBankLegacyMigrate.NOT_FOUND', '_None Found') . '<br/>';
     }
     //Migrate Users
     echo '<b>' . _t('CodeBankLegacyMigrate.MIGRATE_USERS', '_Migrating Users') . '</b>...';
     $results = DB::query('SELECT * FROM "users"');
     if ($results->numRecords() > 0) {
         foreach ($results as $row) {
             if ($row['deleted'] == true) {
                 echo '<br/><i>' . _t('CodeBankLegacyMigrate.DELETED_MEMBER_SKIP', '_WARNING: Skipping deleted member {username}, deleted members in Code Bank 3 are not supported', array('username' => $row['username'])) . '</i><br/>';
                 continue;
             }
             //Get user heartbeat preference
             $useHeartbeat = DB::query('SELECT "value" FROM "preferences" WHERE "code"=\'heartbeat\' AND "fkUser"=' . $row['id'])->value();
             //Insert User
             $member = Member::get()->filter('Email', Convert::raw2sql($row['username']))->first();
             if (empty($member) || $member === false || $member->ID == 0) {
                 $member = new Member();
                 $member->FirstName = $row['username'];
                 $member->Email = $row['username'];
                 $member->Password = $row['password'];
                 $member->PasswordEncryption = 'sha1';
                 $member->Locale = 'en_US';
                 $member->DateFormat = 'MMM d, yyyy';
                 $member->TimeFormat = 'h:mm:ss a';
                 $member->UseHeartbeat = intval($useHeartbeat);
                 $member->write();
                 DB::query('UPDATE "Member" ' . 'SET "Password"=\'' . substr(base_convert($row['password'], 16, 36), 0, 64) . '\', ' . '"Salt"=NULL ' . 'WHERE "ID"=' . $member->ID);
                 //Add to security group
                 if ($row['username'] == 'admin') {
                     //For admin add to administrators group
                     $member->addToGroupByCode('administrators');
                 } else {
                     //For all others add to code-bank-api
                     $member->addToGroupByCode('code-bank-api');
                 }
             } else {
                 //Add to code-bank-api if not admin
                 if ($row['username'] != 'admin') {
                     $member->addToGroupByCode('code-bank-api');
                 }
                 $member->UseHeartbeat = intval($useHeartbeat);
                 $member->write();
                 echo '<br/><i>' . _t('CodeBankLegacyMigrate.MEMBER_EXISTS', '_WARNING: Member {username} already exists in the database, no changes have been made to this member. If you are unsure of the password please ask an administrator to have it reset or use the forgot password link', array('username' => $row['username'])) . '</i><br/>';
             }
         }
         echo _t('CodeBankLegacyMigrate.DONE', '_Done') . '<br/>';
     } else {
         //Rollback Transaction
         if (DB::getConn()->supportsTransactions()) {
             DB::getConn()->transactionRollback();
         }
         echo _t('CodeBankLegacyMigrate.NO_USERS_FOUND', '_No users found, Code Bank 2.2 appears to have not been properly setup cannot continue with migration');
         exit;
     }
     //Migrate IP Message
     echo '<b>Migrating IP Message</b>...';
     $ipMessage = DB::query('SELECT "value" FROM "settings" WHERE "code"=\'ipMessage\'')->value();
     $config = CodeBankConfig::CurrentConfig();
     $config->IPMessage = $ipMessage;
     $config->write();
     echo _t('CodeBankLegacyMigrate.DONE', '_Done') . '<br/>';
     //Migrate Snippets
     echo '<b>' . _t('CodeBankLegacyMigrate.MIGRATE_SNIPPETS', '_Migrating Snippets') . '</b>...';
     $results = DB::query('SELECT "snippits".*, "languages"."language", "creator"."username" AS "creatorUsername", "lastEditor"."username" AS "lastEditorUsername" ' . 'FROM "snippits" ' . 'INNER JOIN "languages" ON "snippits"."fkLanguage"="languages"."id" ' . 'LEFT JOIN "users" "creator" ON "snippits"."fkCreatorUser"="creator"."id" ' . 'LEFT JOIN "users" "lastEditor" ON "snippits"."fkLastEditUser"="lastEditor"."id"');
     if ($results->numRecords() > 0) {
         foreach ($results as $row) {
             //Get Creator ID
             $creator = Member::get()->filter('Email', Convert::raw2sql($row['creatorUsername']))->first();
             if (!empty($creator) && $creator !== false && $creator->ID != 0) {
                 $creatorID = $creator->ID;
             } else {
                 $creatorID = 0;
             }
             //Get Last Editor ID
             $lastEditor = Member::get()->filter('Email', Convert::raw2sql($row['lastEditorUsername']))->first();
             if (!empty($lastEditor) && $lastEditor !== false && $lastEditor->ID != 0) {
                 $lastEditorID = $lastEditor->ID;
             } else {
                 $lastEditorID = 0;
             }
             //Get Language ID
             $language = SnippetLanguage::get()->filter('Name', Convert::raw2sql($row['language']))->first();
             if (!empty($language) && $language !== false && $language->ID != 0) {
                 $languageID = $language->ID;
             } else {
                 $languageID = $plainTextID;
             }
             //Insert Snippet Info
             DB::query('INSERT INTO "Snippet" ("ID", "ClassName", "Created", "LastEdited", "Title", "Description", "Tags", "LanguageID", "CreatorID", "LastEditorID") ' . "VALUES(" . $row['id'] . ",'Snippet','" . date('Y-m-d H:i:s') . "','" . date('Y-m-d H:i:s') . "','" . Convert::raw2sql($row['title']) . "','" . Convert::raw2sql($row['description']) . "','" . Convert::raw2sql($row['tags']) . "'," . $languageID . "," . $creatorID . "," . $lastEditorID . ")");
             //Get History
             $versions = DB::query('SELECT * FROM "snippit_history" WHERE "fkSnippit"=' . $row['id']);
             foreach ($versions as $version) {
                 DB::query('INSERT INTO "SnippetVersion" ("ClassName", "Created", "LastEdited", "Text", "ParentID") ' . "VALUES('SnippetVersion','" . date('Y-m-d H:i:s', strtotime($version['date'])) . "','" . date('Y-m-d H:i:s', strtotime($version['date'])) . "','" . Convert::raw2sql($version['text']) . "'," . $row['id'] . ")");
             }
         }
         echo _t('CodeBankLegacyMigrate.DONE', '_Done') . '<br/>';
     } else {
         echo _t('CodeBankLegacyMigrate.NO_SNIPPETS_FOUND', '_No snippets found') . '<br/>';
     }
     //Rename tables
     DB::getConn()->renameTable('snippits', '_obsolete_snippits');
     DB::getConn()->renameTable('snippit_search', '_obsolete_snippit_search');
     DB::getConn()->renameTable('snippit_history', '_obsolete_snippit_history');
     DB::getConn()->renameTable('languages', '_obsolete_languages');
     DB::getConn()->renameTable('settings', '_obsolete_settings');
     DB::getConn()->renameTable('preferences', '_obsolete_preferences');
     DB::getConn()->renameTable('users', '_obsolete_users');
     //Complete Transaction
     if (DB::getConn()->supportsTransactions()) {
         DB::getConn()->transactionEnd();
     }
     //Mark Migrated
     touch(ASSETS_PATH . '/.codeBankMigrated');
     echo '<br/><h4>' . _t('CodeBankLegacyMigrate.MIGRATION_COMPLETE', '_Migration Completed') . '</h4>';
     exit;
 }
 /**
  * Gets fields used in the cms
  * @return {FieldList} Fields to be used
  */
 public function getCMSFields()
 {
     $fields = new FieldList(new TabSet('Root', new Tab('Main', _t('Snippet.MAIN', '_Main'), DropdownField::create('LanguageID', _t('Snippet.LANGUAGE', '_Language'), SnippetLanguage::get()->where('"SnippetLanguage"."Hidden"=0 OR "SnippetLanguage"."ID"=' . ($this->LanguageID ? $this->LanguageID : 0))->map('ID', 'Title'))->setEmptyString('---'), new TextField('Title', _t('Snippet.TITLE', '_Title'), null, 300), TextareaField::create('Description', _t('Snippet.DESCRIPTION', '_Description'))->setRows(5), PackageSelectionField::create('PackageID', _t('Snippet.PACKAGE', '_Package'), SnippetPackage::get()->map('ID', 'Title'))->setEmptyString(_t('Snippet.NOT_IN_PACKAGE', '_Not Part of a Package')), TextareaField::create('Text', _t('Snippet.CODE', '_Code'), $this->getSnippetText())->setRows(30)->addExtraClass('codeBankFullWidth')->addExtraClass('stacked'), TextareaField::create('Tags', _t('Snippet.TAGS', '_Tags (comma separate)'))->setRows(2))));
     return $fields;
 }
 /**
  * Tests to see that the language only contains three children, the 4th child should be considered a child of the folder
  */
 public function testLanguageChildrenCount()
 {
     $language = SnippetLanguage::get()->filter('Name', 'PHP')->first();
     $this->assertEquals(3, $language->Children()->count(), 'There should be 3 children of the language');
 }
 /**
  * Tests to see if a language defined in the config with a brush that does not end in .js generates an error and is not added
  */
 public function testNonJSCustomLanguageBrush()
 {
     CodeBank::config()->extra_languages = array(array('Name' => 'Test Language 4', 'FileName' => 'tst', 'HighlightCode' => 'tst4', 'Brush' => 'CodeBank/tests/files/testBrush.lorem'));
     $didExpectedError = false;
     try {
         //Try populating the default records
         singleton('SnippetLanguage')->requireDefaultRecords();
     } catch (PHPUnit_Framework_Error_Warning $e) {
         if (strpos($e->getMessage(), 'Invalid snippet user language found in config') !== false) {
             $didExpectedError = true;
         } else {
             throw $e;
             //Ensure the error is re-thrown, it doesn't match what we're expecting
         }
     }
     //Check to see if the error was thrown
     $this->assertEquals(true, $didExpectedError);
     //Make sure it was added
     $this->assertEquals(0, SnippetLanguage::get()->filter('Name', 'Test Language 4')->count(), 'Invalid language was created');
 }