Jump to content

Aaron Ahearne

Members
  • Posts

    23
  • Joined

  • Last visited

Everything posted by Aaron Ahearne

  1. I was using some 3rd party plugins which were proving difficult to configure here. In the end to get form elements I installed this form plugin and all of its dependancies.
  2. Hi, Im trying to allow content managers add custom dropdown into the Body field by adding tools to CKEditor but I cant seem to get any new buttons to appear. Im not entirely sure how which other addons I would need to achieve this either, I've added widgets and line utilities as plugins and I've tried adding 'widget' and 'Widgets' to the CKEditor toolbar textarea when configuring the field, but nothing appears. I've installed them by dropping the downloaded folders into site/modules/InputfieldCKEditor/plugins and then selected them in the 'extra plugins' section of the field config, but still no extra toolbar buttons. Does anyone know how to add new functionality to the CKEditor properly?
  3. So... the cleaner version of the code but Im still having issues. Ideally I would like to know if there is a way of disabling caching before I start the script. $oldNodeModels = wire("pages")->get("name=models, parent.name=home"); if (!is_a($oldNodeModels, NullPage)) { wire("pages")->delete($oldNodeModels, true); } $nodeModels = new Page(); $nodeModels->set("template", "hidden-container"); $nodeModels->set("name", "models"); $nodeModels->set("title", "Models"); $nodeModels->set("parent", wire("pages")->get("name=home")); $nodeModels->save(); $seriesJson = json_decode(file_get_contents("./metadata/models/models.json")); $templateModel = wire("templates")->get("name=model"); if (!$seriesJson) { throw new Exception("/metadata/pages/models/models.json not found"); } if (!$templateModel) { throw new Exception("Missing template"); } if (!$nodeModels) { throw new Exception("Missing Models node"); } echo "\nInstalling Models"; foreach ($seriesJson->models as $modelData) { $modelName = $modelData->{KEY_SERIES} . "-" . $modelData->{KEY_MODEL} . "-" . $modelData->{KEY_MODEL_CODE}; $pageCarSelector = "has_parent=Series," . "has_parent!=Trash," . "body_style_id={$modelData->{KEY_BODY}}," . "include=all"; $pageCar = wire("pages")->get($pageCarSelector); if (is_a($pageCar, NullPage)) { throw new Exception("Car not found with body style ID: " . $modelData->{KEY_BODY}); } $pageModel = new Page(); $pageModel->set("name", $modelName); $pageModel->set("template", $templateModel); $pageModel->set("parent", $nodeModels); $pageModel->set("title", $modelData->{KEY_MODEL}); $pageModel->set("mapped_car", $pageCar); try { wire("pages")->save($pageModel); } catch (Exception $e) { echo $e; } wire("pages")->uncacheAll(); echo "."; }
  4. Im using PHP 5.5.9 MySQL 5.5.46-0ubuntu0.14.04.2 PW 2.6.1 Apache 2.4.7 I've partially overcome this issue for now by deleting the parent and its children, then creating pages from scratch rather than searching and updating (so less caching to handle) and it works OK but this isn't a long term answer. I've noticed that even when separating out this process does not help. I have a similar process which runs before it but does not error. If I run them completely separately they will both work fine, but if they are called directly one after the other it will result in a segmentation fault regardless of the order they are in.
  5. Haha that is correct, is meant to be pageCar, Ill update the code there. That was just a mistake when I was trying to debug. The problem still persists!
  6. $pageModel->save() has the same effect pretty much. Heres an example of that selector for you: has_parent=Series,has_parent!=Trash,body_style_id=F20,include=all
  7. Hi Guys, Im running a script to create a bunch of new pages, but I get a segmentation fault when trying to create/update around 400 pages. function importModels() { echo "Installing Models"; $seriesJson = json_decode(file_get_contents("./metadata/models/models.json")); $templateModel = wire("templates")->get("name=model"); $nodeModels = wire("pages")->get("name=Models, parent=/, include=all"); if (!$seriesJson) { throw new Exception("/metadata/pages/models/models-2.json not found"); } if (!$templateModel) { throw new Exception("Missing template"); } if (!$nodeModels) { throw new Exception("Missing Models node"); } foreach ($seriesJson->models as $modelData) { $modelName = $modelData->{KEY_BODY} . " " . $modelData->{KEY_MODEL_CODE}; $pageCarSelector = "has_parent=Series," . "has_parent!=Trash," . "body_style_id={$modelData->{KEY_BODY}}," . "include=all"; $pageCar = wire("pages")->get($pageCarSelector); if (is_a($pageCar, NullPage)) { throw new Exception("Car not found with body style ID: " . $modelData->{KEY_BODY}); } $pageModel = wire("pages")->get("parent=Models, has_parent!=Trash, template=model, name={$modelName}"); if (is_a($pageModel, NullPage)) { $pageModel = new Page(); $pageModel->set("name", $modelName); $pageModel->set("template", $templateModel); $pageModel->set("parent", $nodeModels); } $pageModel->set("title", $modelData->{KEY_MODEL}); $pageModel->set("mapped_car", $pageCar); $pageModel->set("car_identifier", $modelData->{KEY_MODEL_CODE}); wire("pages")->save($pageModel); echo "."; } echo "\n"; } The problem is not caused by the save, its like wire("pages")->get($pageCarSelector) is doing too much caching. If I add wire("pages")->uncacheAll(); just after the save then it runs a lot further, still eventually breaking. Do you guys have any ideas of any other caches I need to clear to get this working? Many thanks.
  8. To wrap up this subject, I wanted to post some of the code required to handle the file upload. Please let me know if you see any glaring mistakes. I added several hooks to modify the data going into and coming out of ProcessInput for InputfieldFile, that way I managed to grab the file name and store it as part of my form input config in the forms table. Then, when retrieving the data, I had the final part of the file path stored so I could access the image. Unfortunately this does mean that I will need to implement the delete and description functionality of the file uploader myself. public function init() { parent::init(); $this->set("image", ''); $this->addHookBefore("InputfieldFile::processInput", $this, "beforeProcessInput"); $this->addHookAfter("InputfieldFile::processInput", $this, "afterProcessInput"); $this->addHookAfter("InputfieldFile::processInputAddFile", $this, "afterProcessInputAddFile"); } /** * Modify the value property of the InputFieldFile. This sets the form admin page as the value so as to * bypass an error when saving a new image. * @param HookEvent $event */ public function beforeProcessInput(HookEvent $event) { if (!$this->isImageLabelEvent($event)) { return; } $event->object->removeAttr("value"); // sanitise the value field $event->object->set("value", new Pagefiles($this->wire('page'))); } /** * Save the form image to its own directory and save the image path as part of the input field config * @param HookEvent $event */ public function afterProcessInput(HookEvent $event) { if (!$this->isImageLabelEvent($event)) { return; } $uploadedFiles = $event->object->getWireUpload()->getCompletedFilenames(); if (empty($uploadedFiles)) { return; } $formId = wire("input")->get("id"); $form = wire("forms")->get($formId); $imageLabelFieldName = wire("input")->post("field_name"); $imageRadioField = $form->get("children")[$imageLabelFieldName]; $imageFolder = self::DIR_PREFIX . $formId; if ($imageRadioField) { if (!file_exists($imageFolder)) { mkdir($imageFolder); } $imageRadioField->set("image", $imageFolder . "/" . $uploadedFiles[0]); $form->save(); } } /** * Delete the current image once a new one is uploaded * @param HookEvent $event */ public function afterProcessInputAddFile(HookEvent $event) { if (!$this->isImageLabelEvent($event)) { return; } $uploadedFiles = $event->object->getWireUpload()->getCompletedFilenames(); if (empty($uploadedFiles)) { return; } $imagePath = $this->getCurrentImagePath(); if ($imagePath) { unlink($imagePath); } } /** * Create the file input to allow users to override the default series image * @return mixed */ private function createInputFieldFile() { $formId = wire("input")->get("id"); $inputFieldFile = wire('modules')->get('InputfieldFile'); $inputFieldFile->label = $this->_('Image Label'); $inputFieldFile->description = $this->_('Override the series default image.'); $inputFieldFile->extensions = 'jpg jpeg png gif'; $inputFieldFile->maxFiles = 1; $inputFieldFile->maxFileSize = 200000; $inputFieldFile->overwrite = false; $inputFieldFile->destinationPath = $this->getFormImageFilePath($formId); $inputFieldFile->attr('name', self::IMAGE_LABEL_NAME); $inputFieldFile->type = "file"; if ($this->getCurrentImagePath()) { $pageFiles = new Pagefiles($this->wire('page')); $pageFile = new Pagefile($pageFiles, $this->getCurrentImagePath()); $pageFiles->add($pageFile); $inputFieldFile->set('value', $pageFiles); } return $inputFieldFile; }
  9. I think this was an issue to do with the setters in InputfieldFile. As the value is being set as an array, any further setters to value are being set as values in that array. Its just a matter of finding out what is setting it.
  10. I tried manually setting the value of InputFieldFile using a beforeHook on ___processInputAddFile and although it was showing as an array of pagefiles, I was still receiving errors saying that it was attempting to call first() a non-object. Strangely it is showing literally Array[Pagefiles], rather than an instance of WireArray or just a root of page files. Obviously a normal array does not have a first() function, but by creating it manually it should definitely have access to the first() function defined in WireArray. $this->value = new Pagefiles(wire("pages")->get("/offers")); This is not the actual name of my page btw, as Im using the FormBuilder page, so Im just using this page to force something into the db.
  11. Nothing I have tried seems to be working. I cannot use hooks as it will hook every time InputFieldFile is run... unless there is a way to set the hook only when my module is run initialized (setting them in init caused them to run regardless of whether the module was initialized) I just cannot seem to get a value into InputFieldFile. It is always blank. wire('input')->post does not seem to contain any files at all. Even though a file is uploaded to the server. wire('input')->post = {WireInputData} [2] stripSlashes = false data = {array} [16] field_name = "aaa" field_type = "ImageRadios" field_label = "aaa" description = "" notes = "" collapsed = "0" showIf = "" columnWidth = "100%" requiredIf = "" defaultValue = "" options = "Option 1\r\nOption 2\r\nOption 3" optionColumns = "0" _form_id = "4" _field_name = "aaa" _submit_save_field = "Save" TOKEN1788870938X1447321212 = "NmaT7RliGuwEUVaGABrADx/YBdZTiKVf"
  12. Great thanks, thats all I needed to know. I kept getting the error: Call to a member function add() on a non-object (line 373 of /html/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module). I suppose thats because it is expecting an entry in the image table, but it hasnt created one as it has no page to reference. That makes a bit more sense now. Now that Im using the correct Input File module it should be more straight forward. I'll try to set up some hooks to perform after it processes the file and I'll post my solution here once its done.
  13. Hi guys, I have a requirement for a new input field for Form Builder. Essentially I just need to have some radio buttons which use an image as their label. I have managed to create the module, have it install automatically and create a new form with my custom input type but I am having trouble handling the image which is being uploaded as the label. The value for imageLabel is always an empty array. I have looked all around the forums and I Google but I cant find the answer close to what Im looking for. Do I handle the file upload manually and extract/add it to my imageField during POST and GET? I've tried multiple different methods and been through most of the API too but can't figure out the correct way to do this. <?php class InputfieldImageRadios extends InputfieldRadios { const CONFIGNAME = "ImageRadios"; public static function getModuleInfo() { return array( 'title' => __('Radio Buttons with Image Label', __FILE__), 'summary' => __('Radio buttons for selection of a single item with an extra image label', __FILE__), 'version' => 1, 'singular' => true, 'autoload' => true, 'requires' => array('InputfieldRadios', "FormBuilder") ); } public function init() { parent::init(); } public function ___getConfigInputFields() { $inputFields = parent::___getConfigInputfields(); $imageField = wire('modules')->get('InputfieldFile'); $imageField->label = $this->_('Image Label'); $imageField->description = $this->_('If you want the label to be displayed as an image.'); $imageField->extensions = 'jpg jpeg png gif'; $imageField->maxFiles = 1; $imageField->maxFileSize = 200000; $imageField->overwrite = false; $imageField->destinationPath = wire("config")->paths->files . "radioLabels/"; $imageField->name = "imageLabel"; $imageField->type = 'file'; $imageField->value = array(); $inputFields->add($imageField); return $inputFields; } public function set($key, $value) { if($key == 'imageLabel') { $test = 1; } return parent::set($key, $value); } /** * Install the module append to Form Builder config * */ public function ___install() { $formBuilderClass = "FormBuilder"; $this->verifyDependencies([$formBuilderClass]); $formBuilderConfig = wire("modules")->getModuleConfigData($formBuilderClass); if (in_array(self::CONFIGNAME, $formBuilderConfig['inputfieldClasses'])) { return; } $formBuilderConfig['inputfieldClasses'][] = self::CONFIGNAME; wire("modules")->saveModuleConfigData($formBuilderClass, $formBuilderConfig); } protected function verifyDependencies($classes) { foreach ($classes as $class) { if (!wire('modules')->isInstalled($class)) { $this->error(self::CONFIGNAME . " dependency not installed: $class"); } } } /** * Uninstall the module and remove from Form Builder config * */ public function ___uninstall() { $formBuilderClass = "FormBuilder"; $this->verifyDependencies([$formBuilderClass]); $formBuilderConfig = wire("modules")->getModuleConfigData($formBuilderClass); foreach ($formBuilderConfig['inputfieldClasses'] as $key => $value) { if ($value == self::CONFIGNAME) { unset($formBuilderConfig['inputfieldClasses'][$key]); } } wire("modules")->saveModuleConfigData($formBuilderClass, $formBuilderConfig); } }
  14. Ok so that has fixed it. As suspected, the previous install attempts had caused $this->installable to be populated incorrectly. Although FormBuilder did not appear in the Modules table, it was still being detected as installed. I'm not sure how the installable array in Modules is being populated so I don't know the root cause of it. Thanks so much for your help on this. I'd been through all of the tutorials but this has given me a far greater understanding of PW. I was even able to remove some of the data from my stored config as this final approach auto populated some of it for me.
  15. Yes, I am able to install via the admin interface. Im wondering if I've just corrupted the install from my previous attempt. I've found the problem. In Modules.php line 1221. $installable = array_key_exists($class, $this->installable); I can see that $this->installable essentially has a list of installable modules. FormBuilder does not appear in this list. Im going to do a fresh install of ProcessWire now to see if that fixes my problem.
  16. Thank you so much for taking the time to look at this. Your comments are really helpful. Unfortunately, at the moment the following line is still returning null. $formbuilder = wire('modules')->install("FormBuilder"); Im going to have a further look into it and take a further look into the docs in your comments and see if I can figure out what is going on.
  17. echo "Starting...\n"; include_once("../index.php"); if (!$modules->isInstalled("FormBuilder")) { require_once("./modules/FormBuilder/FormBuilder.module"); include_once("./install-config.php"); echo "Installing Form Builder\n"; echo "-------------------\n"; if (!file_exists("./install-config.php")) { echo "install-config.php not found"; die(); } // Get license key from config file if (!$config->formBuilderLicenseKey) { echo "Missing Form Builder license key"; die(); } // Create cache directory $filesPath = "./assets/cache/form-builder"; if (!is_dir($filesPath)) { if (!is_dir($filesPath)) { if (!is_dir("./assets/cache")) { mkdir("./assets/cache"); } mkdir($filesPath); echo "Creating formbuilder cache directory at " . $filesPath . "\n"; } } $formBuilder = new FormBuilder(); $formBuilder->___install(); $data = json_decode(file_get_contents("./metadata/formBuilder/modules.json"), true); /** * Install config data */ if ($data) { foreach ($data as $class => $data) { if ($class === "FormBuilder") { $data['licenseKey'] = $config->formBuilderLicenseKey; } wire("modules")->saveModuleConfigData($class, $data); } closedir($handle); } }
  18. Thanks LostKobrakai thanks for the tips. I've been looking at that forum post for the whole day trying to figure out why mine isnt working. FormBuilder isnt actually showing up in my modules table at all, Im wondering if this is why it cant find it. Even using wire("modules")->saveModuleConfigData("FormBuilder", $data); it is telling me that it cannot find an ID for FormBuilder. Im guessing this row should be created via ___ those hooks when FormBuilder installs itself? FYI, Im using all of these functions outside of any scope pretty much, just a plain PHP script. Im not sure its a possibility to use it inside its own class, but wire() is resolving to an object, so Im guessing it is somewhat inside of a ProcessWire scope.
  19. Thanks for your help guys. I've managed to get something going, just on one last section that Im struggling with. A very simple version of what I have done: require_once("./modules/FormBuilder/FormBuilder.module"); $formBuilder = new FormBuilder(); $formBuilder->___install(); I have done it this way as I am storing the formbuilder files in the GIT repo, this way I just need to tell the server to install them the first time around. I'm having some trouble getting the modules table to populate. I was previously setting it manually with raw SQL, but I want to use the API. My code is: $modules->___saveModuleConfigData($class, $data); The class is "FormBuilder" and the data is just a string. But I get the error: Uncaught exception 'WireException' with message 'Unable to find ID for Module 'FormBuilder'' in /vagrant/oliver2/html/wire/core/Modules.php:2544 I have tried using $modules->___install("FormBuilder") and using $modules->get("FormBuilder") to get it to install the config in the modules table, but no luck. Trying to use $modules->___install() returns null because it stops at line 1255: if(!$this->isInstallable($class)) return null; I'm really stuck on what I need to do to get this module config installed. Any ideas?
  20. Thanks LostKobrakai, thats really helpful. I can use adapt this into roughly what I need. That looks like a Symfony migration though, are you using this code from a separate system? You're extending Migration (thats why I assume Symfony) and using $this, which would have no scope outside of this code. Just curious. That CLI tool will definitely come in useful at some point, thanks kongondo. Ryan, I'd love that code snippet, unfortunately its not my FormBuilder key so I dont want to risk giving it out, even though Im pretty sure you are the legit Ryan!
  21. Adrian that is almost what I was looking for but there is a lot of GUI interaction still. The code is still helpful and I may be able to use the export function with some custom code to automatically load in the modules. LostKobrakai your module sounds exactly like what I need. Do you have a module or a github page where I could take a look at your process? Adding in full migrations would be ideal and we can definitely call them from a deployment script. The only issue I can see with both solutions is that it migrates the config, so I assume it is storing the licence keys in a database migration file (as the licence keys are part of the module config object contained in the db). If this is the case, they will definitely need extracting to a file that is not synced with the repository.
  22. Hi, I've recently started on a team using Processwire, so Im quite new to it but I've had plenty of experience with Symfony2. We have an agency licence for the FormBuilder module and we want to use some sort of CI to deploy. When you first install FormBuilder module, it creates some new tables and requires some set up via a GUI including adding a licence key. We have looked into containing our licence key in a config file, then using some JSON files to sync to the database. This doesn't give us a lot of control and requires a fair bit of custom migrations. Is there a way to deploy a ProcessWire site including the FormBuilder module without going through the GUI setup every time? If not, Are there any migration modules for ProcessWire? If not, are there any recommended third party migration tools that are frequently used with ProcessWire? Many thanks!
×
×
  • Create New...