Jump to content
Macrura

Settings Factory

Recommended Posts

@Macrura First of all: Thanks for this great module. I noticed it already when you first released it, but because there was no real for it in my own projects, I never installed it till now.

I found a confusing behavior (bug?) when I use the kitchen sink example.

No matter what email address I try, PW always shows me an error: "InputfieldEmail: Please enter a valid e-mail address - Email Test"

It doesn't matter if I use a real, existing email, or just a semantically correct one.

What's even more strange is that this red error shows up on every page in the PW admin - literally everywhere.

Am I missing something obvious? PW throwing an error if a required field is empty or doesn't match some regex rules is one thing, but that should only be visible in the respective page-edit screen, not globally? The only thing I noticed: There is no "autoload disabled" checkbox in module/edit?name=ProcessSettingsFactory

I'm using SF 1.0.3 and
ProcessWire: 3.0.149
PHP: 7.3.13
Webserver: Apache/2.4.35 (Win64) OpenSSL/1.1.1d
MySQL: 5.7.24

settings-factory.thumb.PNG.f8141d1df02d2d324e03c99e89c8ff98.PNG

Edited by dragan
added screenshot
  • Like 1

Share this post


Link to post
Share on other sites

strange that you'd be running SF 1.0.3 as the 1.0.4 version has been out for over a year- can you double check it is version 1.0.4?

This is the 2nd report of this issue, and i have not been able to reproduce it – are you using the kitchen sink JSON or PHP version (shouldn't matter though).

If I can reproduce this, i think it can be fixed - but i'm not clear where to look;

I guess once you confirm it is 1.0.4, or upgrade to that, if the problem persists, i will keep trying;

I'm running tests on PHP 7.3.1, PW 3.0.148, MySQL 5.7.25

 

Share this post


Link to post
Share on other sites

@Macrura I'll try and give some more information.

Version: it seems SF installs actually two modules. One is v. 1.0.4, the other 1.0.3. Since I just installed it 1-2 days ago, it's unlikely I accidentally picked an old version.

I'm using the JSON kitchen sink version.

I de-installed SF y'day and installed again today. The same issues persist.

I attached a few screenshots.

before installing:

settings-factory-before-installing.PNG.3ee297adc1dd4d8f9cc632bb7cfe3b96.PNG

after installation:

settings-factory-after-installing.PNG.c4fc8319aaa1ef10a6b325fb57ed34db.PNG

after installation, under modules (notice versions 1.0.3 + 1.0.4)

settings-factory-versions.PNG.7c58630a38c2022d22089af12e3f0f5b.PNG

Trying to update process SF:

settings-factory-versions-notfound.thumb.PNG.65d9e408cbd33e5efbd23e9d14f81c09.PNG

editing the page under /admin: the page I entered for the JSON is 100% correct:

settings-factory-admin-page-settings.thumb.PNG.d06ae81bb9b35781d139a451df8fac30.PNG

Thanks a lot for looking into it.

 

Share this post


Link to post
Share on other sites

So the issue is simply that in multilanguage environments, it seems to behave differently; all you need to do is change the value from "0" to an empty string and it should solve this. I will update the kitchen sink example to fix this in multilang environs.

it should be pointed out that what this module really does is to basically use all core functions for rendering the fields; So in this case the issue was really stemming from how the field was being defined, and we didn't catch it because we didn't test the kitchen sink file in multilang.

Share this post


Link to post
Share on other sites

this also does bring up whether the settings should be always processed on every admin page load, or if the settings loading should be skipped in admin;

Share this post


Link to post
Share on other sites

Hello @Macrura, great module.
Can you please tell me a way to store a setting value using API instead of writing it in the setting page manually? thanks

Share this post


Link to post
Share on other sites

@Sevarf2 - I was able to successfully do that by adding a custom setConfigDataCustom method to the module, but this would be a beta feature until it is tested further. I'm not totally sure if i'm doing it the best/right way, so this was just a quick test, but it did work.

However the api is not so intuitive for this currently as you first need to get the settings array for the key, then alter the value of one of the items, or add a new item (not tested) and then write the whole array back to the module

$factory = $modules->get("SettingsFactory");
$mySettings = $factory->getSettings('wiretabs-testing1',false); // return array not wiredata
$mySettings['settings_client'] = 'Jimmy James 4th';
$factory->setConfigDataCustom('wiretabs-testing1',$mySettings);

I think it might also be possible to write settings to the module that don't have process pages, using this, but not sure how useful that is, i assume that it will be possible since the settings are just module config, so you'd be able to store anything you'd want in those arrays...

If you can elaborate on the use case for this that might help to determine the best way to implement it.

  • Like 1

Share this post


Link to post
Share on other sites

thanks for the quick reply.
I have 2 parameters , api Client ID and api Client Secret of a rest api i'm accessing to retrieve some data. I insert those values manually one time. Now, when I use the API I'm getting in return another value, a PolicyKey (for another request) that I need to store for 6 days until it changes again, so I would like to store this value with the other two in the settings panel and I cannot insert it manually

Share this post


Link to post
Share on other sites

ok thanks - i think it can be done no problem, but i think the api should be cleaner where you don't need to deal with setting array values; i'll have to post back once i have a working prototype.

 

  • Like 1

Share this post


Link to post
Share on other sites

@Sevarf2 If you want to test this, you can add the following code to the module at the end of "SettingsFactory.module".

	/**
	 * @var $key - the settings key
	 * @var $_key - the setting within the key
	 * @var $value - the new value
	 */
	public function changeSetting($key,$_key,$value) {
		$modData = $this->modules->getConfig('SettingsFactory');
		if(!array_key_exists($key, $modData)) return;
		if(!array_key_exists($_key, $modData[$key])) return;
		$modData[$key][$_key] = $value;
		$this->modules->saveModuleConfigData('SettingsFactory', $modData);
	}

and then this would be the way to change the setting from api:

$factory->changeSetting('wiretabs-testing1','settings_client','new value');

in limited testing this has worked fine, but i'd recommend a few more tests before using on production. I haven't commited this to the master yet - it probably needs to include a check to ensure the target key exists in this case.

This also illustrates that it would be possible to add settings (addSetting), but since the fieldset is defined in a hard file, any settings added in the api would not be editable in the admin, so not sure if that would be useful.

  • Like 1

Share this post


Link to post
Share on other sites

thanks, that's great, I will add the code and test it

Share this post


Link to post
Share on other sites

@Sevarf2 - just updated the code to ensure that both the settings array and the key within the array exist. (This would prevent inadvertently adding a settings array or setting if the key is typed incorrectly), if they don't it will ignore the changeSetting() call.

  • Like 1

Share this post


Link to post
Share on other sites

@Macrura First of all I love SettingsFactory!

I've seen notices before in SettingsFactory when I add new fields but not yet saved the value.
In this complicated setup I have here this notice prevents the PageList from being loaded.

SettingFactory->getSettings() triggers the notice on line 152.

// Locally i have changed the if statemaent on line 151:
} else {
	$newDataArray[$key] = $dataArray[$key];
}

// To this:
} else if (isset($dataArray[$key])) {
	$newDataArray[$key] = $dataArray[$key];
}

Without looking much in to this, this fixes it for me.

 

  • Like 1

Share this post


Link to post
Share on other sites

@Martijn Geerts - many thanks for taking the time to make the fix here!

I will implement is and do some tests and update the module soon.

 

  • Like 1

Share this post


Link to post
Share on other sites
On 6/5/2020 at 10:43 PM, Macrura said:

@Martijn Geerts - many thanks for taking the time to make the fix here!

I will implement is and do some tests and update the module soon.

 

Any update? I can't download the module, even from github, it's no longer available?

Share this post


Link to post
Share on other sites
13 minutes ago, Sevarf2 said:

Any update? I can't download the module, even from github, it's no longer available?

Looks like GitHub itself is down right now, so this probably has nothing to do with SettingsFactory 🙂

  • Like 2

Share this post


Link to post
Share on other sites
Just now, teppo said:

Looks like GitHub itself is down right now, so this probably has nothing to do with SettingsFactory 🙂

Ops, didn't check github itself...thanks 🙂

Share this post


Link to post
Share on other sites
13 hours ago, Sevarf2 said:

Any update? I can't download the module, even from github, it's no longer available?

Hi @Sevarf2 - i haven't tested the mod, so was hesitant to commit the change, but i should be able to do it this week. Are you having the same issue as Martijn?

Share this post


Link to post
Share on other sites

Hi, it's ok, it was just the fact that github was down and I didn't notice it, so I thought you kind removed the module for some reason / imminent update, sorry 🙂

Share this post


Link to post
Share on other sites

I ran into an unusual situation, I've tried a number of things to remedy it but have had no luck.

When using an InputfieldPageAutocomplete, I have the following setup:

    {
      "name":"header_font",
      "label":"Header Font",
      "type":"InputfieldPageAutocomplete",
      "width":"100",
      "parent_id":1305,
      "maxSelectedItem":1,
      "description":"Page List Select Test Description",
      "collapsed":0,
      "value":"0",
       "columnWidth":20
     },

I am able to type fields, get results and all is good. For some reason that I cannot explain, the single page item that gets saved there started out as being stored in the index [0] for the output array, but after saving the control value with a blank entry and then selecting an entry, now for some reason the index is shifted to [1]. There are things I can do to check for this and use the value, but I am really trying to understand the shift. If I do a tracy dump, it shows the index in the array should be 0, there is only one item in the PageArray. But when I try to extract the settings and call the header_font[0] item, I get an undefined index: 0 error and if I change it to header_font[1] item, the only selected item works as usual.

The weird thing is that it was working fine when I first added the field and saved a value - did a bunch of testing with it, no problem. After I cleared the value, saved, and then inserted a new value I started running into the weird index reset.

I'm not really sure where to go next, when the tracy d() output suggests there is only one item in the PageArray and it somehow is not at the 0 index marker.

Share this post


Link to post
Share on other sites

@gornycreative - thanks for the report, i will test this and post back asap.

  • Thanks 1

Share this post


Link to post
Share on other sites

@gornycreative -

you can try changing this line (221)

$valuesArray[$key] = $f->attr('value');

to this:

$valuesArray[$key] = is_array($f->attr('value')) ? array_values($f->attr('value')) : $f->attr('value');

which should always force any value that is an array to reindex to 0 based.

Let me know if that solves it.

Share this post


Link to post
Share on other sites
22 hours ago, Macrura said:

@gornycreative -

you can try changing this line (221)


$valuesArray[$key] = $f->attr('value');

to this:


$valuesArray[$key] = is_array($f->attr('value')) ? array_values($f->attr('value')) : $f->attr('value');

which should always force any value that is an array to reindex to 0 based.

Let me know if that solves it.

I will give it a try.

I don't know (again) what happened, but after a few hours trying it again resolved the issue. I'm not entirely sure what caused the original issue or why it was resolved. Perhaps cloudflare said I was logged in and had toggles activated on their UI even though I wasn't logged in? I am not entirely sure. Not great for debugging when the problem solves itself 😕

The inconsistency with how Tracy dumps said one thing but some other calls provdided errors - not a lot made sense (which seems much of the time to be caching somewhere).

It doesn't look like the host made any significant config changes anyplace I have access to.

UPDATE: Regardless, the fix provided consistent results.

Share this post


Link to post
Share on other sites

@gornycreative 

Currently the fix for the issue you reported is the one i provided. I don't know the internal specifics, but the arrays are not reset when saving the value/processing the form the first time, which is why I had to force any array value to a new array.

So you will end up with no [0] index item under some circumstances unless you apply the fix.

You can test it by dumping the value and then adding items to any multi page reference field, and then removing them one by one and hit save and look at the arrays.

Also note that any 2nd save of the settings page does reset the arrays fully. It must be something to do with where/which hook we are processing the form input; For now this is a safe fix, and i'll cary on researching any further optimizations, but this may be the resolution.

  • Thanks 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By hellerdruck
      Hi all
      I need to export all the texts from a website to a translation company (as json or csv or txt...). How can this be done? Of course manually, but this website is huge and it would take me years...
      Also, as a second step, importing the translation ...
      Any ideas anyone? Tutorials? Plugins?
      Thanks for your help.
    • By jonatan
      So... I thought (for some stupid reason I can't even recall now no wait now I remember.. I wanted to hide the "Trash" for "editor" role users) that it'd be super duper smart to "Enable access control" for the field "process" on the admin template.... Really really stupid.... Now all I get is:

       
       
       
      – when I go to mywebsitedomain.com/admin
      but.... my website domain.com and all its subpages works perfectly fine! So it's ONLY the /admin (processwire) which throws a 503 at me. 
      🥵🤯☠️💩😭😱
      S.O.S.
    • By Ivan Gretsky
      Most of us know and use site/config-dev.php file. If present, it is used instead of site/config.php, so it is easy to set database connection and debug mode for local development, not touching the production config. It is also very useful when working with git. You can simply ignore it in the .gitignore file, so local settings won’t end up in the repo.
      But sometimes you need to add code to site/ready.php or site/init.php just for the dev environment. For example, to add ryan’s super cool on demand images mirrorer. I can’t live without it when working with big sites, which have more assets then I want to download to my desktop.
      It would be great if there was something like site/ready-dev.php for this. Not out-of-the-box, but it’s pretty easy to achieve. Unlike site/config-dev.php, site/ready.php is not hardcoded. It’s name is set with a special config setting:
      // wire/config.php $config->statusFiles = array( 'boot' => '', 'initBefore' => '', 'init' => 'init.php', 'readyBefore' => '', 'ready' => 'ready.php', 'readySite' => '', 'readyAdmin' => '', 'render' => '', 'download' => '', 'finished' => 'finished.php', 'failed' => '', ); As you can see, we can not only define, which files are loaded on init, ready and finished runtime states, but probably even add more if we need to.
      So we override this setting in site/config-dev.php like this:
      // site/config-dev.php // Change ready.php to ready-dev.php $temp = $config->statusFiles; $temp['ready'] = 'ready-dev.php'; $config->statusFiles = $temp; For some reason we can’t just do
      $config->statusFiles['ready'] = 'ready-dev.php'; and have to override the whole array. Maybe you PHP gurus can explain this in the comments.
      Now we can create the site/ready-dev.php file and place all the dev-only code there. Important thing is to include the main site/ready.php.
      // site/ready-dev.php include 'ready.php'; // DEV HOOK TO MIRROR ASSETS ON DEMAND $wire->addHookAfter('Pagefile::url, Pagefile::filename', function($event) { $config = $event->wire('config'); $file = $event->return; if($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if(!file_exists($file)) { // download file from source if it doesn't exist here $src = 'https://mysite.com/site/assets/files/'; $url = str_replace($config->paths->files, $src, $file); $http = new WireHttp(); try { $http->download($url, $file); } catch (\Exception $e) { bd($file, "Missing file"); } } }); Do not forget to replace "mysite.com" if you’re copypasting this))
      Now, add the newly created file to the `.gitignore` and we’re done.
       
      # .gitignore # Ignore dev files site/config-dev.php site/ready-dev.php Thanks for reading!
       
    • By MoritzLost
      Sorry for the convoluted title. I have a problem with Process modules that define a custom page using the page key through getModuleInfo (as demonstrated in this excellent tutorial by @bernhard). Those pages are created automatically when the module is installed. The problem is that the title of the page only gets set in the current language. That's not a problem if the current language (language of the superuser who is installing the module) is the default language; if it isn't, the Process page is missing a title in the default language. This has the very awkward effect that a user using the backend in the default language (or any other language) will see an empty entry in the setup menu:

      This screenshot comes from my Cache Control module which includes a Process page. Now I realize the description sounds obscure, but for us it's a common setup: We a multiple bilingual sites where the default language is German and the second language is English. While the clients use the CMS in German, as a developer I prefer the English interface, so whenever I install a Process module I get this problem.
      As a module author, is there a way to handle this situation? I guess it would be possible to use post-installation hooks or create the pages manually, but I very much prefer the declarative approach. The page title is already translatable (through the __ function), but of course at the time of installation there is no translation, and as far as I'm aware it's not possible to ship translations with a module so they are used automatically. Could this situation be handled better in the core? I would prefer if the module installation process would always set the title of the Process page in the default language, instead of the language of the current user.
    • By MoritzLost
      Process Cache Control
      This module provides a simple solution to clearing all your cache layers at once, and an extensible interface to perform various cache-related actions.
      The simple motivation behind this module was that I was tired of manually clearing caches in several places after deploying a change on a live site. The basic purpose of this module is a simple Clear all caches link in the Setup menu which clears out all caches, no matter where they hide. You can customize what exactly the module does through it's configuration menu:
      Expire or delete all cache entries in the database, or selectively clear caches by namespace ($cache API) Clear the the template render cache. Clear out specific folders inside your site's cache directory (/site/assets/cache) Clear the ProCache page render cache (if your site is using ProCache) Refresh version strings for static assets to bust client-side browser caches (this requires some setup, see the full documentation for details). This is the basic function of the module. However, you can also add different cache management action through the API and execute them through the module's interface. For this advanced usage, the module provides:
      An interface to see all available cache actions and execute them. A system log and logging output on the module page to see verify what the module is doing. A CacheControlTools class with utility functions to clear out different caches. An API to add cache actions, execute them programmatically and even modify the default action. Permission management, allowing you granular control over which user roles can execute which actions. The complete documentation can be found in the module's README.
      Plans for improvements
      If there is some interest in this, I plan to expand this to a more general cache management solution. I particular, I would like to add additional cache actions. Some ideas that came to mind:
      Warming up the template render cache for publicly accessible pages. Removing all active user sessions. Let me know if you have more suggestions!
      Links
      https://github.com/MoritzLost/ProcessCacheControl ProcessCacheControl in the Module directory CHANGELOG in the repository Screenshots


×
×
  • Create New...