Search the Community
Showing results for 'runtime'.
-
I don't know homebrew, but to me it looks like the ini setting for "always_populate_raw_post_data" isn't (finally) set to -1. Have you checked it on runtime? The issue simply is, that you get a PHP warning as return of an ajax request, what then breaks your app (PW), as it expects another return, (a json object, and not a PHP server warning). You need to disable all php warning output, other then logfile, you need to check your ini settings for the mentioned setting on runtime, and / or you should set the mentioned setting on runtime too. Sometimes there are multiple php.ini files on a system, and it isn't quite obvious which one(s) are involved. So, additionally you may scan your filesystem for all php.ini files and explicitly set "always_populate_raw_post_data" to -1 in every file, if the runtime check shows that it isn't set to this.
-
@olafgleba Edit your /site/config.php file and look for: $config->httpHost and/or $config->httpHosts. In most cases the $config->httpHost should not be present (since PW will set it automatically at runtime), but the $config->httpHosts (plural) should be present, and it should be an array of http hosts ProcessWire is allowed to auto-detect and use. It will pick one of the hosts in that array to use for the request, so long as it matches the $_SERVER[HTTP_HOST]. If it can't find one that matches the $_SERVER[HTTP_HOST] then it will simply use the first one in your httpHosts array: $config->httpHosts = [ 'www.company.com', 'dev.company.com', 'localhost:8888' ]; If it just contains one host then it'll always use that one, regardless of what's in $_SERVER[HTTP_HOSTS] … $config->httpHosts = [ 'www.company.com' ]; If you do have the non-plural $config->httpHost present (like below), then it forces use of that hostname, rather than letting PW auto-detect from your httpHosts array. Though if there's only one host in your httpHosts array (like above) then of course the effect would be the same. $config->httpHost = 'www.company.com'; My best guess is that you either have $config->httpHost or httpHosts set with '127.0.0.1', or that you have httpHost/httpHosts undefined in your /site/config.php file. To fix it you need to add your www.host.tld to a $config->httpHosts array and preferably as the first item in it. If you do see a $config->httpHost (non-plural) in your config.php them I would remove it.
-
@Matzn Your TestModuleChild.module is overriding the getModuleConfigInputfields() of the TestModule.module and replacing it. In PHP, if you want the parent method to run, then you need to either omit the method completely in your child class, or call the method parent::method() so that it will run (like what you are doing with your __construct method). What you are doing currently is replacing the method with one that has no code in it. What I think you are wanting is this in your TestModuleChild.module: public function getModuleConfigInputfields(InputfieldWrapper $inputfields) { parent::getModuleConfigInputfields($inputfields); } After doing the above, now it will inherit the code of the parent class. And after calling that parent::method() maybe you want to add another configuration setting to it, i.e. public function getModuleConfigInputfields(InputfieldWrapper $inputfields) { parent::getModuleConfigInputfields($inputfields); $f = $this->wire()->modules->get('InputfieldText'); $f->attr('name', 'test_field'); $f->label = 'Test field'; $f->val($this->test_field); $inputfields->add($f); } But if you don't want to add anything new to the getModuleConfigInputfields() then just leave the method out of your TestModuleChild.module completely, and it will inherit automatically. Also, module configuration data should be defined with runtime calls, so I recommend you remove this: public $field_1 = "parent module property 1"; and replace it with this in your __construct(): $this->set('field_1', 'parent module property 1'); I see you are using static getModuleInfo() methods in your classes. In cases where you've got one module extending another, unless the child module literally does an include() at the top of the parent module's file, then you should define your child module's info in a ModuleName.info.php file like I described in my previous message (including the 'requires' statement), and omit the getModuleInfo() static method. Otherwise, if PHP/PW happens to include() the child module before the parent module, you'll get a fatal class error. By using a separate ModuleName.info.php, PW can learn about the module without having to load the class file, and it can see from your 'requires' statement that it needs to load the parent module before your child module, ensuring no fatal errors. If you can't do this, or don't want to, then make sure your child module does an include() or require() of the parent module's file, somewhere before your "class TestModuleChild ...".
-
I followed some sample modules to start my first project. The module installs/uninstalls fine but when I click the module's page I get the following error: Fatal Error: Uncaught TypeError: Argument 1 passed to ProcessWire\ProcessController::getProcessMethodName() must be an instance of ProcessWire\Process, instance of ProcessWire\GoodNews given, called in /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php on line 324 and defined in /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php:260 Stack trace: #0 /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php(324): ProcessWire\ProcessController->getProcessMethodName(Object(ProcessWire\GoodNews)) #1 /Users/mgartner/ProjekteWEB/processwire/wire/core/Wire.php(380): ProcessWire\ProcessController->___execute() #2 /Users/mgartner/ProjekteWEB/processwire/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___execute', Array) #3 /Users/mgartner/ProjekteWEB/processwire/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessController), 'execute', Array) #4 /Users/mgartner/ProjekteWEB/processwire/wire/core/admin.php(135): ProcessWire\Wire->__ca (line 260 of /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php) This error message was shown because: you are logged in as a Superuser. Error has been logged. Here is the full source: <?php namespace ProcessWire; /** * GoodNews module * * An integrated group and newsletter mailing system for Processwire. * * This file is licensed under the MIT license * https://processwire.com/about/license/mit/ * * ProcessWire 3.x, Copyright 2016 by Ryan Cramer * https://processwire.com * */ class GoodNews extends WireData implements Module { const debug = false; const pageName = 'goodnews'; const minVersionPHP = '5.6.37'; /** * Required by all modules to tell ProcessWire about them * * @return array */ public static function getModuleinfo() { return array( // The module's title, typically a little more descriptive than the class name 'title' => 'GoodNews', // A brief description of what this module is 'summary' => 'An integrated group and newsletter mailing system.', // Module version number: use 1 for 0.0.1 or 100 for 1.0.0, and so on 'version' => 1, // Name of module author 'author' => 'Martin Gartner, bitego', // Optional URL to more information about the module 'href' => 'http://modules.processwire.com/goodnews', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. //'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). //'autoload' => true, // For more options that you may specify here, see the file: /wire/core/Process.php // and the file: /wire/core/Module.php ); } public function execute() { if (version_compare(PHP_VERSION, self::minVersionPHP) >= 0) { // good } else { $this->error("Please note that your current PHP version (" . PHP_VERSION . ") is not adequate to run this module."); } $out = 'Test'; return $out; } /** * Executed on install */ public function ___install() { // Create the page the module will be assigned to $page = new Page(); $page->template = 'admin'; $page->name = self::pageName; // Installs to the admin main menu $page->parent = $this->pages->get($this->config->adminRootPageID); //->child('name=setup'); $page->process = $this; // Page title is the same as our module title $info = self::getModuleInfo(); $page->title = $info['title']; // Save the page $page->save(); // Tell the user we created this page $this->message("Created Page: {$page->path}"); } /** * Executed on uninstall */ public function ___uninstall() { // Find the page we installed, locating it by the process field (which has the module ID) // It would probably be sufficient just to locate by name, but this is just to be extra sure. $moduleID = $this->modules->getModuleID($this); $page = $this->pages->get("template=admin, process=$moduleID, name=" . self::pageName); if($page->id) { // If we found the page, let the user know and delete it $this->message("Deleting Page: {$page->path}"); $page->delete(); } } } Any hints? Thanks, Martin
-
Repeater Items - How to filter "ready items" - Bug?
SiNNuT replied to Luke Solar's topic in API & Templates
I think i can at least shed some light on where status 3073 is coming from in the DB. If you take a a look at Page.php (in the wire/core folder) you see this: /* * The following constant flags are specific to a Page's 'status' field. A page can have 1 or more flags using bitwise logic. * Status levels 1024 and above are excluded from search by the core. Status levels 16384 and above are runtime only and not * stored in the DB unless for logging or page history. * * If the under 1024 status flags are expanded in the future, it must be ensured that the combined value of the searchable flags * never exceeds 1024, otherwise issues in Pages::find() will need to be considered. * * The status levels 16384 and above can safely be changed as needed as they are runtime only. * */ const statusOn = 1; // base status for all pages const statusLocked = 4; // page locked for changes. Not enforced by the core, but checked by Process modules. const statusSystemID = 8; // page is for the system and may not be deleted or have it's id changed (everything else, okay) const statusSystem = 16; // page is for the system and may not be deleted or have it's id, name, template or parent changed const statusHidden = 1024; // page is excluded selector methods like $pages->find() and $page->children() unless status is specified, like "status&1" const statusUnpublished = 2048; // page is not published and is not renderable. const statusTrash = 8192; // page is in the trash const statusDeleted = 16384; // page is deleted (runtime only) const statusSystemOverride = 32768; // page is in a state where system flags may be overridden const statusCorrupted = 131072; // page was corrupted at runtime and is NOT saveable: see setFieldValue() and $outputFormatting. (runtime) const statusMax = 9999999; // number to use for max status comparisons, runtime only So i think 3073 comes from the combined values of statusOn, statusHidden and statusUnpublished. One would assume that pages, like readypages, with a code > 1024 would be excluded by default in finding and listing repeater items. I have looked through the FieldtypeRepeater code to see what's going on but this is beyond my php skills and knowledge of the core system. Maybe Ryan can comment on this. For the moment i think your filter solution seems fine. I you want to read more on status stuff i suggest you do a 'find in files' for 'status'. Tools like Sublime Text then give a nice overview of the search results. Not really slick docs..but good for learning :) -
https://github.com/horst-n/WireMailSmtp/issues/14 "I" get them too, in php 7.4 In php 7.4 get_magic_quotes_runtime() is deprecated but still exists, so function_exists("get_magic_quotes_runtime") has no effect to stop the deprication message from appearing. https://www.php.net/manual/en/function.get-magic-quotes-runtime.php "REMOVED as of PHP 8.0.0." so function_exists("get_magic_quotes_runtime") bit works as expected in PHP 8 and up.
-
@horst could you please have a look at this issue? https://www.php.net/manual/en/function.get-magic-quotes-runtime.php Thx!
-
ProcessWire 3.0.193 resolves 6 issues, makes improvements to the template and module editors, adds new hooks, adds improvements the $pages->find() findRaw method, and more. We covered some of these updates in last week's post, so we'll focus on what's new this week. First off we have a new advanced mode feature that lets you edit the raw configuration data for a module. This can be useful for various reasons, especially for module developers. If you have $config->advanced = true; in your /site/config.php file, you'll see a new option on your module information screen that enables you to directly edit the raw JSON configuration data for the module. There's also an option that lets you view the raw JSON module information data. Unlike the configuration data, this isn't editable. That's because it comes from the module directly (overtime you do a Modules > Refresh) or is generated at runtime, so there's little point in editing it here. In my case, I've found these new tools helpful for clearing out old and/or irrelevant configuration data during module development. In some cases, having the ability to edit this data may help to identify or fix issues that previously would have been difficult to do without using the API. If there's interest, I may move this into a dedicated (non-core) module that also lets you directly edit field and template configuration data too. But for now the feature is in the core, but just requires advanced mode before it appears. A few new hooks were added this week: Fieldgroups::fieldRemoved($fieldgroup, $field) Called after a field has been removed from a fieldgroup/template. Fieldgroups::fieldAdded($fieldgroup, $field) Called after a new field has been added to a fieldgroup/template. Fieldgroups::renameReady($template, $oldName, $newName) Called before a fieldgroup is about to be renamed. Fieldgroups::renamed($template, $oldName, $newName) Called after a fieldgroup has been renamed. Templates::renameReady($template, $oldName, $newName) Called before a template is about to be renamed. Templates::renamed($template, $oldName, $newName) Called after a template has been renamed. Fields::renameReady($field, $oldName, $newName) Called before a field is about to be renamed. Fields::renamed($field, $oldName, $newName) Called after a field has been renamed. These accompany the existing addReady(), added(), deleteReady(), deleted(), cloneReady(), cloned(), saveReady() and saved() hooks available for fields, templates and fieldgroups. Last week a couple people asked about versioning and migration of stuff in PW (like fields, templates, modules, etc.) and if there were any plans to provide additional tools for that. For the projects I work on at least, this part of the development process consumes so little time that it doesn't warrant developing more stuff for it. But I understand others might find it useful, so for those that would, I'd rather keep the core lean and instead leave that to tools/modules built by experts like Bernhard and others around here. I think it's important that whoever develops and maintains such features also be the same one(s) that would use them. But if any kind of core updates would be helpful to developers looking to implement more features here, I'm on board. Whether that means adding more hooks to specific events (see above as examples), maintaining field/template/module data in files in addition to the current DB tables, or anything else that helps such modules, this is all possible and likely simple for us to support in the core. So just let me know what I can do to help. While not full-featured migration tools, we do have useful field, template and page export/import tools in the core already, and those will of course continue to be maintained and improved, and may be expanded to include modules too. Thanks for reading and have a great weekend!
- 26 replies
-
- 16
-
-
We're in the last steps of phasing out the project I was using it on. Most parts had been replaced years ago since we moved away from processwire with that project. The module's approach to access is nice, but iirc there were some bugs in the master implementation and we actually would've needed a bit more flexibility out of it (still needed code to create those dynamic roles). I'd still suggest it over expensive runtime access checks if it aligns to a projects access setup. We've been using it because our access was not only scoped by roles, but also by customers. So a manager would only have access to manager pages, which belonged to a customer assigned to that manager. Customers weren't static, but also defined by pages within the system. Things also weren't segmented into individual page trees, though iirc the modules for segmenting by page tree didn't exist at that time as well.
-
Not another Markup Fieldtype ? https://github.com/BernhardBaumrock/FieldtypeRockMarkup What do you think of a Fieldtype that does nothing else then rendering runtime markup from files that you provide in the settings or at runtime? In addition to that, I'd like the field to trigger javascript events to be usable for other fieldtype modules (like a charts module or a grid module). Javascript events would be necessary on field load (ajax/non-ajax), on collapse of the field, on click of a tab. When working with charts and RockGrid this has sometimes become a pain and I've implemented (sometimes dirty) fixes for that in different modules in different ways. I think it would make sense to have a solid base for such kind of modules (fieldtypes) that use some kind of standard events for standard situations. I'm especially interested in your opinions @Beluga because of the upcoming RockTabulator module and @kongondo because of your existing module. I think there are already similar modules by @Robin S and @kixe ? Thx for your input ?
-
Fieldtype that just displays HTML, nothing else
MarkE replied to DrQuincy's topic in Getting Started
https://processwire.com/modules/inputfield-runtime-only/ ? -
Hi @Abe Cube I you are talking about ProcessPageEdit screen, that you can add runtime fields via hook. You can find some info there
-
Determining the context a page is being created in [solved]
FireWire replied to FireWire's topic in API & Templates
I think your solution works for a bigger context of where a lot of data on a page would be dependent on the context it was created in. I just needed to make sure that the hook for one field can determine at runtime whether the field was filled by a user in the PW admin or the Page API. Your solution from the PW admin side did make me think bigger picture which is also a possible solution for my application. This field is being used on pages that can be created/edited in the ProcessWire admin, but they can also be created/modified by a website REST API that other systems- in our case Salesforce- can use to create/modify data on the site. Calls to this website API are authenticated using ProcessWire users which have an API key assigned and a role of web-api-access. So rather than focus on verifying where the the page was created at the field level, I could check that the user creating the field is an API user at the page level. I got a little more into the weeds with that description, but your idea helped me think of a different approach. -
Determining the context a page is being created in [solved]
bernhard replied to FireWire's topic in API & Templates
Sounds like you can simply set a flag at runtime: <?php // your script that creates the json page $page = new Page(); ... $page->createdViaApi = true; $page->save(); Then your hook should be able to catch that flag: <?php $wire->addHookAfter("Pages::saveReady", function($event) { $page = $event->arguments(0); if($page->createdViaApi) { // check and throw exception } else { // check and show error to user } }); -
I'm a little late to the game on this but wanted to throw out what we use on our PW sites. We keep all credentials in .env files in the root directory and then loaded using a package called phpdotenv. The .env file is loaded and then the credentials can be accessed at runtime via the $_ENV global. Some further details on this setup: .env files are automatically protected system files in Apache and will not be served (unless someone actively overrides this, but that would be bad). These files are not added to the Git repository and never stored. We have .env files for local, staging, and production. The contents of each file are stored in whole as a secure note in our password manager. The dotenv library is loaded once in config.php and the values are available globally. We also store credentials for external APIs and services. This allows us to store not only credentials, but any values that differ between local/staging/production. We store all of our config.php variable values in .env so that the config.php file is environment agnostic and we can always be sure that the .env is the single source of truth for the entire CMS configuration. We use Git to deploy to staging/production servers so using .env files allows us to push all of our code while knowing that sensitive information and data that changes between environments never gets mixed up. Also makes it very clear to anyone looking at the code that these values are stored in a dedicated system dot file. Here's the package, can be installed with composer https://github.com/vlucas/phpdotenv This is what a config.php file looks like with it in use: <?php namespace ProcessWire; // Load env variables from .env in root directory $dotenv = \Dotenv\Dotenv::createImmutable(__DIR__ . '/../'); $dotenv->load(); $config->debug = filter_var($_ENV['CMS_DEBUG'], FILTER_VALIDATE_BOOLEAN); $config->usePageClasses = filter_var($_ENV['CMS_USE_PAGE_CLASSES'], FILTER_VALIDATE_BOOLEAN); $config->useFunctionsAPI = filter_var($_ENV['CMS_USE_FUNCTIONS_API'], FILTER_VALIDATE_BOOLEAN); /** * Database Configuration */ $config->dbHost = $_ENV['CMS_DB_HOST']; $config->dbName = $_ENV['CMS_DB_NAME']; $config->dbUser = $_ENV['CMS_DB_USER']; $config->dbPass = $_ENV['CMS_DB_PASS']; $config->dbPort = $_ENV['CMS_DB_PORT']; $config->dbEngine = $_ENV['CMS_DB_ENGINE']; // Etc... Hope this might be useful to someone!
- 6 replies
-
- 10
-
-
@Ivan Gretsky That part I know I can handle. It's the front-end JS side of it that I don't know a lot about, yet. I mean this just to suggest the possibility of establishing some sort of guidelines for how a developer might implement selective rendering. I don't know what those guidelines would be, and just use that GET var as an example of how a request might indicate a change for a particular field (named "body"). Trying to communicate that in the simplest example possible. The developer would decide what that meant in terms of output that should be produced. But perhaps this example is too far from the context, I'm still learning how this SSE stuff works. PW can't generate partial markup for anything (outside of the admin at least), so it would be up to the site developer to implement whatever methodology we suggest for this, at least if they want higher performance live updates. From what I can tell, htmx can handle both cases... replacing partial markup, or selecting a part (hx-select) from a larger portion of markup, like the full document. @kongondo Yes you are right, it wouldn't be very practical. But the benefits of selective markup rendering may be enough that it's worthwhile for us to establish some guidelines for supporting selective rendering. Like that ?change=body example earlier, that's what I was trying to communicate there even if it's likely not a good example. The guidelines could be as simple as just letting the site developer know when they can skip over expensive things to render, like primary navigation or footer, etc. Something like if($config->livePreview) { // skip rendering unnecessary primary navigation } else { // render primary navigation } I was actually thinking of "body" as a PW field name, and the developer would decide what that means to the output in terms of what should be replaced. But you guys have a lot more experience with htmx than me so I think my example is likely flying a little blind, as my focus so far as only been on the auto-save part that identifies field changes. I need to start playing with htmx. ? The way that ProDrafts live preview works is by having the editor window communicate to the preview window and notify it when a field changes (JS based window-to-window communication). The preview window does pull a fresh/updated copy of the rendered page, but it attempts to only replace the markup that changed. It does this by having formatted values for fields like "body" include an extra <div> around them that identifies what it is, and then ProDrafts can replace just that element with JS. You can see things as you type in the editor, with a short delay, unless your page is very slow to render. This works well for formatted text fields (which is usually most of what one wants to see in live preview), but it does have to refresh the full document for other things where the site developer may be responsible for more runtime markup related to the field output. @monollonom ProDrafts only reloads the whole frame as a last resort. For most cases it can update just what changed. This is helpful for avoiding a very visible and distracting page refresh. Such page refreshes kind of kill the live-preview effect and can more easily draw your attention away from the content you are working on. I don't know if it'll be necessary to introduce a 3rd party dependency or not (htmx), but it does seem like a good place to start, even if we end up rolling our own later. That's more the domain of ProDrafts, and PagesSnapshots (another module in development). I think any kind of core autosave and live preview will focus on just those features (autosave and live updated view) and making them as good as they can be. It might be that one only wants to use these features for unpublished pages, but I think that's where it is most useful in the first place. If you wanted autosave/live preview on a published page, you could always clone it and then replace the original (or not) when you were done. This is essentially how PagesSnapshots manages drafts.
-
max file size validation for file/image fields
horst replied to chrizz's topic in Wishlist & Roadmap
@chrizz your calculation is totally wrong. Only thing that is of interest for imagesizer is uncompressed image in memory. You do not hit a filesize limit, you hit a memory limit. Why you run into it, I can't say. But I can say that we do runtime checks for available memory before opening an image in memory, but also we use a fast calculation depending on most common images for that. Without seeing your original images, I guess your original image has some image markers like EXIF, IPTC, VENDOR-Tags etc. what may be a little over the top of what we use for our precalculation. Theoretically it is possible to pack a lot of data into this, but typically it isn't that big. Maybe an edgecase? (Calculation like we do, fits just into available runtime memory, but without the ImageMarkers?) But one thing is a physical fact: FilesizeCompression cannot reduce needed memory limit. (and therefor I do not need deep theory, this is simply how computers work since ever. In my earlier days, around 1994, we sometimes do some jokes: we compressed big dimensioned jpeg images with the lowest quality setting / highest compression rate, and send them as previews to Artdirectors with a question to them. Always when they tried to display it, it got loaded / uncompressed into memory and their systems imediately got freezed / unusable. So, we only have done that to very unfriendly people who really deserverd a little shock. ) So, what ever you have changed in your second saved imagefile, what is responsible for the fit into memory than, it is not filesize compression. A serious test would need to log the runtime available memory for both images before trying to open it, and the same after they allocated the memory, and compare all that. Also a full check of all file parts in the imagefile (markers and image data). Without that, it says null to nothing and only opens room for glasball looking, guessing or misinterpretions. -
I don't think this is right. My runtime Fieldtype is based off Ryan's Concatenate Fieldtype and that does not create a DB table. See also his comments in the code, e.g. this one. No database table is necessary.
-
Been getting a similar error on a custom runtime module. Only way around it is to specify a field/fields to fetch as in your example.
-
$pages->find() not respecting my Pages::viewable() hook
szabesz replied to thetuningspoon's topic in API & Templates
Here is a discussion related to this issue, in which Ryan explains the API decisions: https://processwire.com/talk/topic/11736-get-requests-not-subject-to-access-control To sum it up real quick (quotes): A $pages->find() or $pages->findOne() method that filters results is based on database-filtering, not runtime filtering. The API is based around providing methods for the developer to control access the way they see fit. The viewable() method is the basis of that. PW's access control model supports runtime hooks to Page::viewable. One shouldn't skip a $page->viewable() call regardless of what method you used to retrieve the page. When rendering frontend templates <?php if ($page->viewable()) : ?> (or $page->viewable('field_name'); ) is the way to go to check for default PW permissions. For example: https://processwire.com/talk/topic/4834-simple-hooks-tutorial-turn-a-pagearray-into-a-list-of-links/ ... // loop through each item in the PageArray and render some links foreach($event->object as $page) { $value = $page->get($property); if(!strlen($value)) continue; // skip empty values if(strlen($out)) $out .= $delimiter; if($page->viewable()) { $out .= "<a href='$page->url'>$value</a>"; // if page is viewable, make it a link } else { $out .= $value; // if page is not viewable, just display the value } } ... In order to "extend" the access control logic, one can hook after Page::viewable eg.: https://github.com/processwire/processwire-issues/issues/560#issuecomment-384656192 quote: // goes into /site/ready.php $wire->addHookAfter('Page::viewable', function($event) { $viewable = $event->return; if($viewable) return; // use PW's existing logic, since it said it was viewable $page = $event->object; if(!$page instanceof User) return; // this is an example for User templates only if(whatever logic you decide that $page is viewable) { $viewable = true; $event->return = $viewable; } }); -
As I've mentioned svelte already and the filesize argument was used: https://v3.svelte.technology/repl?version=3.0.0-beta.22&example=onmount This example downloaded and compiled results in a 4kb javascript bundle. I'm quite sure even just the code using jquery would need about half of that size to do the same excluding jquery itself. So there are more modern ways to have the benefits of a nice view library in javascript without the need for bloated runtime library code. Svelte has a tiny runtime library, which can even be tree shaken (only include what's needed), while the heavy lifting is done at once at compile time. The better part of your file size bundle will only consist of the actual stuff you build using it. It's only sad that it's currently in a "please don't start using v2 anymore, but also wait till v3 is done" phase.
-
Hi you might call it dumb, but this is actually interesting, I was thinking is there any mechanism to /condition to stop a Hook from being called, so pardon this jargon, so I took the time to see if such exists public function runHooks($method, $arguments, $type = 'method') { $result = array( 'return' => null, 'numHooksRun' => 0, 'methodExists' => false, 'replace' => false, ); $realMethod = "___$method"; if($type == 'method') $result['methodExists'] = method_exists($this, $realMethod); if(!$result['methodExists'] && !self::isHooked($method . ($type == 'method' ? '()' : ''))) { return $result; // The condition for not running is when not hooked or method doesn't exist } $hooks = $this->getHooks($method); foreach(array('before', 'after') as $when) { if($type === 'method' && $when === 'after' && $result['replace'] !== true) { if($result['methodExists']) { $result['return'] = call_user_func_array(array($this, $realMethod), $arguments); } else { $result['return'] = null; } } foreach($hooks as $priority => $hook) { if(!$hook['options'][$when]) continue; if(!empty($hook['options']['objMatch'])) { $objMatch = $hook['options']['objMatch']; // object match comparison to determine at runtime whether to execute the hook if(is_object($objMatch)) { if(!$objMatch->matches($this)) continue; } else { if(((string) $this) != $objMatch) continue; } } if($type == 'method' && !empty($hook['options']['argMatch'])) { // argument comparison to determine at runtime whether to execute the hook $argMatches = $hook['options']['argMatch']; $matches = true; foreach($argMatches as $argKey => $argMatch) { $argVal = isset($arguments[$argKey]) ? $arguments[$argKey] : null; if(is_object($argMatch)) { // Selectors object if(is_object($argVal)) { $matches = $argMatch->matches($argVal); } else { // we don't work with non-object here $matches = false; } } else { if(is_array($argVal)) { // match any array element $matches = in_array($argMatch, $argVal); } else { // exact string match $matches = $argMatch == $argVal; } } if(!$matches) break; } if(!$matches) continue; // don't run hook } $event = new HookEvent(); $event->object = $this; $event->method = $method; $event->arguments = $arguments; $event->when = $when; $event->return = $result['return']; $event->id = $hook['id']; $event->options = $hook['options']; $toObject = $hook['toObject']; $toMethod = $hook['toMethod']; if(is_null($toObject)) $toMethod($event); else $toObject->$toMethod($event); $result['numHooksRun']++; if($when == 'before') { $arguments = $event->arguments; $result['replace'] = $event->replace === true || $result['replace'] === true; if($result['replace']) $result['return'] = $event->return; } if($when == 'after') $result['return'] = $event->return; } } return $result; } As you can see there isn't any logic to stop hooks from running other than if the arguments are wrong and method doesn't exist or the method itself in question is not hookable. However using an exit should work since the exit method stop the execution of the current script. I think the concept of Hooks is you attaching to them and not stopping them. But another alternative would be to remove the check from the hook and and have the check determining whether to call the WireHttp::send Let me know if that suffices
-
I was just trying to think if there was a way to achieve what I wanted without changes to the module. I saw that the module was adding the import/export features according to a permission so thought I might be able to grant that permission selectively at runtime. But I later realised that the permission is checked at the ready state rather than before the InputfieldTable render so even if my idea was possible I'd have to set the permission at every page load which would be a bit over the top. I think that a couple of extra checkboxes on each Table field config would be ideal - something like "Allow CSV export" and "Allow CSV import", although it would still depend on the user having the relevant permissions so there should probably be a note about that. Existing users of the module would expect to have these options checked on all existing fields and I guess you could deal with that in the module upgrade() method. Thanks!
-
module gets auto-installed if called from front-end?
applab replied to applab's topic in Module/Plugin Development
Hi @Zeka, Yes, I am using $modules->get("MyModule") in my front-end template. I was just surprised to see MyModule get installed as a result of that code rather than throwing an error, which is what I was expecting. I've achieved my original goal of preventing the install in that situation but I've realised that I still need to use isInstalled() in my front-end templates to avoid runtime errors so, thanks. -
Dynamic Roles are a powerful access control tool for ProcessWire. They pick up where traditional roles leave off, and allow you to assign permissions at runtime based on any factor present with the user. Once a user receives one or more dynamic roles (at runtime), those dynamic roles then specify what pages the user can view, edit, or add children to. If traditional roles are a sledgehammer, Dynamic Roles are a scalpel, allowing nearly any finely tuned access control scenario. Traditional ProcessWire roles are limited to assignment of view/edit/add access on a per-template basis. Dynamic roles go outside those limitations and enable you to assign that access based on any factors present with a page (i.e. match any field values). Dynamic Roles assign new access, but do not revoke existing access provided by traditional roles. As a result, Dynamic Roles can be used together with traditional roles, and the two work beautifully well together. Though Dynamic Roles can also replace all situations where you would use traditional roles for access control assignments. If using Dynamic Roles to assign page-view access, you would typically want to use traditional roles to revoke view access from at least the "guest" role at the template level. Then use Dynamic Roles to assign view access to those pages in a more granular manner. This module directly affects the results of all page getting/finding operations by applying the access control directly to the database queries before pages are loaded. As a result, it is fast (regardless of scale), pagination friendly, and requires no further intervention by the developer other than configuring the dynamic roles as they see fit. Because it relies upon new features present only in ProcessWire 2.4.6+, it requires the current dev branch. Sponsored by Avoine Concept by Antti Peisa Code by Ryan Cramer PLEASE NOTE: This module is in pre-release state (like the PW dev branch it requires) and is not recommended for production use just yet. Though we do appreciate any testing and/or feedback that you are able to provide. While not required, this module benefits from ProFields Multiplier. If you have ProFields Multiplier installed before installing this module, it will make this module more powerful by making all of your access control selectors have the ability to use OR-group conditions. Depending on your access control needs, this enables you to accomplish more with fewer Dynamic Roles. How to install Make sure you are running ProcessWire 2.4.6 (dev branch) or newer. Download from GitHub (we will add this module to the Modules directory later). Place all files from this module in /site/modules/DynamicRoles/. In your admin, go to Modules > Check for new modules. Click "install" for the Dynamic Roles module (ProcessDynamicRoles). Click to Access > Dynamic Roles for the rest (see example and instructions below). Example and instructions Lets say you ran a Skyscrapers site and wanted a role enabling users with "portmanusa.com" in their email address to have edit access to skyscrapers designed by architect John Portman, with at least 40 floors, and built on-or-after 1970. Yes, this is an incredibly contrived example, but it is an example that also demonstrates the access control potential of this module. 1. In your admin, you would click to Access > Dynamic Roles. 2. Click "Add Dynamic Role". Enter a name for the dynamic role, like: "skyscraper-test-editor" and save. 3. Under "Who is in this dynamic role?" section, click "Add Field" and choose: Email => Contains Text => "portmanusa.com". This will match all users having "portmanusa.com" in their email address. 4. Under "permissions" check the boxes for: page-view and page-edit. 5. For this contrived example, we will assume the user already has view access to all skyscrapers, so we will leave the "What can they view?" section alone. 6. For the "What can they edit?" section: Click "Add Field" and choose: template => Equals => Skyscraper. Click "Add Field" and choose: architect => Equals => John Portman. Click "Add Field" and choose: floors => Greater Than Or Equal => 40. Click "Add Field" and choose: year => Greater Than Or Equal => 1970. 7. Click Save. Now users matching the conditions of your dynamic role will be able to edit the matching pages, but not any others (unless assigned by traditional roles).
- 65 replies
-
- 48
-