Jump to content

Search the Community

Showing results for 'runtime'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Welcome to ProcessWire
    • News & Announcements
    • Showcase
    • Wishlist & Roadmap
  • Community Support
    • Getting Started
    • Tutorials
    • FAQs
    • General Support
    • API & Templates
    • Modules/Plugins
    • Themes and Profiles
    • Multi-Language Support
    • Security
    • Jobs
  • Off Topic
    • Pub
    • Dev Talk

Product Groups

  • Form Builder
  • ProFields
  • ProCache
  • ProMailer
  • Login Register Pro
  • ProDrafts
  • ListerPro
  • ProDevTools
  • Likes
  • Custom Development

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

  1. This week’s dev branch version brings you improvements to ProcessWire’s $input->cookie API variable, plus it adds the ability to modify system URLs and paths at runtime. This post also includes some examples to demonstrate just how useful this can be— https://processwire.com/blog/posts/pw-3.0.141/
  2. You can just change $page->template->contentType and $page->template->altFilename at runtime… $html = $page->render(); $page->template->contentType = 'txt'; $page->template->altFilename = "Mail.txt.php"; $txt = $page->render(); $count = $this->mail->new() ->subject($subject) ->body($txt) ->bodyHTML($html) ->send(); For me, altFilename actually is enough…
  3. That's not really true. Ryan's Dynamic Roles module does add additional sql clauses to ensure dynamic roles are fully resolved at the database level. Sadly is the module is not very well maintained and it could also be build a bit more flexible (e.g. matching on calculated values instead of just "membership"), but it is possible. This to me sounds like a very hacky workaround. You initially said you don't want to bloat the system with hooks. Blacklisting IDs and filtering them at runtime is very likely to be way worse for performance than a handful or two more hooks.
  4. Hello @kongondo Any news on this issue? I also run into it when trying to export a textarea field via the standard field export feature of the admin. I don't really need Runtime Markup, maybe you can give me a quick guide on how to remove it manually (inluding how to clean up the db if needed?). Has this version been version published yet? Thanks in advance.
  5. Here's what the code actually says. In the Page class, we have these constants: 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 const statusMax = 9999999; // number to use for max status comparisons, runtime only These are all the possible values for status. However, status is a bitmask, so it can have more than one value at a time. However, the status levels are ordered from most visible to least visible, so selectors like "include=all" actually translate to "status<9999999" and "include=hidden" translates to "status<2048". Next is the PageFinder class, which is where the "include=all" and "include=hidden" are defined, among other things. There is also an internal mode in PageFinder called "findOne" that is an option that the $pages->get() function uses. The findOne option is not one that you would use on your own, it's only an internal designation. The findOne option states that: 1) return only the first match; 2) skip over any access control checks; 3) limit to pages with status less than unpublished (unless another status is specified or include=all is specified). There is also the "findAll" option, which is what is assumed when you specify "include=all". That one states that 1) the status must be less than statusMax (meaning, it can include any available status); and 2) skip over any access control checks. Again, you don't need to remember what findOne and findAll are, since you won't ever use them. But I mention them just to explain how selectors translate in the system. $pages->get() or $pages->find() are not going to include pages in the trash unless you specify an "include=all" or one of the high status levels. $pages->get() is different from $pages->find() in these respects: $pages->get() only ever returns 1 page. $pages->get() bypasses access control and will include hidden pages. You don't need to specify "include=all" to $pages->get(); unless you want to retrieve an unpublished page or a page from the trash. If there are times when you want a $pages->get() that performs exactly like $pages->find(), except only returning one page, you can do this: $page = $pages->find("your selector, limit=1")->first(); if($page) { // you got it } Or you can do this: $page = $pages->get("your selector"); if($page->viewable() && !$page->isHidden()) { // you got it } I almost never need to do any this though (or necessarily even remember it). $pages->find() behaves the way I usually want it to, including things that aren't viewable and things that don't belong in lists and navigation. And $pages->get() behaves the way I usually want it to, returning the single specific thing that I asked for.
  6. Once a system has a page-publish permission, it changes the behavior of page-edit as well. From that point forward, a user with page-edit permission must also have page-publish permission in order to edit a published page. The "who can access this page?" screen is telling you as much as it can about individual roles, but it's not telling you anything about combinations of roles. If a page is published, and there is a role that has page-edit, but not page-publish, then it's going to say it's not editable by that role. And that's true, because if you take that role by itself, the page isn't editable. Likewise, if you've got a role with page-publish, but not page-edit, a user with that role by itself can't edit anything. So this information section can't tell you anything about what might be the results of combining roles. Since that is determined at runtime, specific to a user, the only way you can tell is to try it with an actual user. Before I experiment too much here, I should check if you are testing by logging in as the user, or just by looking at what this info screen says? Stacked permissions should still work for the actual user at runtime. Though let me know if you find they aren't? These settings are cached with the template. So it may say one thing here based on that cached state, but again the runtime result of the actual permissions for a user should be consistent with the user's actual permissions. Let me know if you find it is not, as that would be a bug. I agree this must look confusing. Those checkboxes are getting populated with the cached value from the template. It sounds like what I need to do here is prevent "disabled" attribute checkboxes from having a checked value.
  7. Thanks for the reply @horst! I was kind of hoping to get some feedback from you. I fully get the point about issue with uncontrolled auto mode but I don't quite understand what you mean by binding compression to defined suffix option. Currently auto mode is hooked after Pageimage::size and (if enabled) compression is done when given size is allowed, type matches (png/jpeg) and API is available (client connected and monthly compression limit no exceeded). By adding custom image sizer option we could disable auto compression on cases where further image manipulation is done and then handle it manually last in chain or do you have something more sophisticated in mind? $image->width(300, array('tinify'=>false))->pimLoad('prefix')->someManipulations()->pimSave()->tinify(); By the time it's also not prohibited to do re-compression to the images - maybe we should restrict such a use cases: // tinify already tinifyed image $page->image->tinify()->tinify(); // tinify resisized (and compressed) image when auto mode is enabled $page->image->size(100,100)->tinify(); I was thinking about forcing (jpeg) quality to 100% but then I thought we don't need that since if one want's to compress images sized at lower quality, why to restrain that. But when you say lower quality actually makes higher filesize we sure need forced 100%. Since compression is done to existing pageimages, we can only force 100% when image is resized by PW. Do you think something like this could work or again, do you have something else in mind? 1. Hook before Pageimage::size - Check for compression and if ok, save filename to runtime variable. 2. Hook before ImageSizer::resize - Set pageimage quality to 100% if jpeg and filename matches to the one in runtime var. 3. Hook after Pageimage::size - Do the compression and return tiny variation of a pageimage. Also I'd need your help (or maybe from @ryan) with resized images on rich text editors. First I thought hooking Pageimage::size would take care of this one also since it looks like that here in ProcessPageEditImageSelect::executeResize() but for some reason hook doesn't bite. Can you tell me why?
  8. When you insert an image through CKEditor, ideally I'd want to grab the description from the image's description field. CKEditor Inputfields fields have an option called "Image management" that should enable this: https://processwire.com/docs/fields/textarea-fieldtype/#markup-html-option I just can't get this to work well, if I add a new image to the text fields, their descriptions are not pulled from the images. My bad again man, I kept on reviewing this on the CKeditor source and just realized this is done on runtime.
  9. Hi everyone! Does anyone know if this has been fixed in recent versions? Still broken for me on 3.0.136 My bad here, I kept on reviewing the source code in CKEditor and this is done at runtime.
  10. Sure, why not? Perhaps you don't even need a module for this. Just some custom HTML with an anchor .pw-modal which opens your page. With one of the three "runtime markup" modules that would be easy to do, I guess: https://processwire.com/talk/topic/21982-rockmarkup-inputfield-to-easily-include-any-phphtmljscss-in-the-pw-admin/ (this is the latest one of this kind, afaik). Is your general goal to have something like a central image library for often-used assets?
  11. Why not use pages and proper Fieldtype fields to store the data? Seems like it would be much easier, and anything out-of-the-ordinary that you want to show within your Process module you could show within Page Edit by hooking the render of a markup inputfield, or by using one of the runtime field modules from kongondo, bernhard, kixe, or me.
  12. @Juergen this is too much for monday! haha. But you know, looking at the config page, this list probably generated on runtime because there is also no way to delete them on the config screen, I took a look at the source code and I THINK, it's happening here, so maybe you can call executeNavJSON?: https://github.com/processwire/processwire/blob/master/wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module#L151
  13. I was wondering which logic is behind the httpUrl method when multiple hosts are availble? My config says $config->httpHosts = array('api.local', 'www.api.local', '10.0.1.10'); $page->httpUrl returns always api.local. In the current setup 10.0.1.10 would be appreciated. Is there any logic behind this or is just the first host taken for the httpUrl() call? Checking the code brings up this comment But: How is this runtime valued defined when I use this method in a hook?
  14. I don't understand if the total code is random as in, generated on runtime (like and shop's order id?) or if it can exist as another page and be referenced.
  15. Inputfield Page Source Display a string with the rendered output of the Page (per it's Template) in an Inputfield. The markup could be copied with a button click (flash enabled browsers) and/or copied manually from the Inputfield. The rendered output is a runtime only value which is not stored in the database. Potential Use Provide an easy way for editors to copy the sourcecode of the page for the use in newsletter services and such. Note ! This Inputfield should not be used in the page template directly. (could give some “funky” results ) Download on GitHub
  16. To store data in a database table there's no need for any custom fieldtype. These are only needed if you want to create custom fields. If your module does just need a place to store e.g. configuration, you could also just use standard sql queries and if that's to bare bone there's always the option to let a orm library handle it or rather any library that abstracts the sql queries for you. There's also the option to use the module configuration automatisms to store information, which is stored json encoded, but might be enough for smaller configurations. It's true that fieldtype development is not very well documented officially, but it's actually not much different from what the teaser video in the starting post does show besides the UI factor. It needs a table column setup (getDatabaseSchema()) and some runtime to database conversion (sleepValue()) and db to runtime conversion (wakeupValue()). While the fieldtype events plugin is mentioned in the forum as kind of entry point to fieldtype development I found it a bit overwhelming at first, as it's starting out as multi-value field and is therefore more complex than it would need to be in the beginnings. With just extending the core fieldtype class and changing up those three methods you should be able to get a fieldtype working and then you can add functionality like sanitization or subfields and so on on top of it.
  17. When using PW's API, you should always consider your code to be operating as a kind of superuser, just like in PHP. In find() operations where you are retrieving multiple pages that you don't know exactly what they will all be, it's a sensible default to exclude "hidden", "unpublished" and no access pages, unless you request otherwise. This is there as a matter of convenience and pagination, not security. Of course you can override that (when you want to) with the "include=hidden" or "include=unpublished" or "include=all" options. Whereas with get() you are being very specific about what you want–a single specific page. Otherwise why would you get() it? Neither find() or get() are intended as a primary means of access control–we have other methods for that (see below). They are methods setup to operate in the most common use cases and keep your API calls as short and simple as possible. Just because find() filters out hidden, unpublished and no-access pages by default does not mean you should count on it for access control. That's because the pages excluded from a find() don't include runtime access control, just that which is stored in the DB. Further, the behavior of whether or not a no-access page shows up in a find() result (that isn't overridden with an include= directive) is configurable with template access settings. Granted, in most cases find()'s defaults are giving you exactly what you want in terms of excluding pages the user can't view (for your convenience), but that's not the entirely of PW's access control, which supports runtime hooks. PW's job is to provide access control for the request, but not for your own code, that's the developers job. PW intends to give you, the developer, access to everything (like you would with jQuery and the DOM), and you decide whether or not it should be available for output. PW provides you with some handy access control methods to help with this: $page->viewable(); // is the page viewable? true or false $page->viewable('field_name'); // is the field on page viewable? true or false $page->editable(); // is the page editable? true or false $page->editable('field_name'); // is the field on page editable? true or false If you want to have you own get() and find() that operate under different defaults, this is easy to do with hooks in your /site/ready.php file. For instance, this would add a $pages->one("selector"); method that automatically does a viewable() check for you and returns a NullPage() if the page is not viewable: $pages->addHook('one', function($event) { $page = $event->object->get($event->arguments(0)); if($page->id && !$page->viewable()) $page = new NullPage(); $event->return = $page; }); Would there be value in adding a method like the above to our $pages API by default? Maybe. It wouldn't benefit my own API use, because the only time I use $pages->get() is because I want to get something without conditions. But if it would be super handy for others I'm happy to add it. Here's another example, lets say you want a method in $pages, like $pages->all("selector"); that always returns all pages with "include=all" implied: $pages->addHook('all', function($event) { $event->return = $event->object->find($event->arguments[0], array('include' => 'all')); });
  18. v0.0.6 adds support for runtime fields, that means you can now use mathparser in your processmodules as well just by specifying one property: /** @var InputfieldDecimal $f */ $f = $this->modules->get('InputfieldDecimal'); $f->label = "foo"; $f->attr('id+name', "bar"); $f->mathParser = true;
  19. My htaccess file is this: ################################################################################################# # START PROCESSWIRE HTACCESS DIRECTIVES # @version 3.0 # @indexVersion 300 ################################################################################################# # ----------------------------------------------------------------------------------------------- # 1. Don't show directory indexes, but do follow symbolic links # 500 NOTE: Some cloud hosting companies don't allow +SymLinksIfOwnerMatch. # Uncomment +SymLinksifOwnerMatch and comment +SymLinksIfOwnerMatch if you have 500 errors. # If that doesn't resolve the error, then set it back to +SymLinksIfOwnerMatch. # ----------------------------------------------------------------------------------------------- Options -Indexes Options +SymLinksIfOwnerMatch # Options +SymLinksifOwnerMatch # ----------------------------------------------------------------------------------------------- # 2. Let ProcessWire handle 404s # ----------------------------------------------------------------------------------------------- ErrorDocument 404 /index.php # ----------------------------------------------------------------------------------------------- # 3. Handle request for missing favicon.ico/robots.txt files (no ending quote for Apache 1.3) # ----------------------------------------------------------------------------------------------- <Files favicon.ico> ErrorDocument 404 "The requested file favicon.ico was not found. </Files> <Files robots.txt> ErrorDocument 404 "The requested file robots.txt was not found. </Files> # ----------------------------------------------------------------------------------------------- # 4. Protect from XSS with Apache headers # ----------------------------------------------------------------------------------------------- <IfModule mod_headers.c> # prevent site from being loaded in an iframe on another site # you will need to remove this one if you want to allow external iframes Header always append X-Frame-Options SAMEORIGIN # to prevent cross site scripting (IE8+ proprietary) Header set X-XSS-Protection "1; mode=block" # prevent mime-based attacks via content sniffing (IE+Chrome) # Header set X-Content-Type-Options "nosniff" </IfModule> # ----------------------------------------------------------------------------------------------- # 5. Protect ProcessWire system files # ----------------------------------------------------------------------------------------------- <FilesMatch "\.(inc|info|info\.json|module|sh|sql)$|^\..*$|composer\.(json|lock)$"> <IfModule mod_authz_core.c> Require all denied </IfModule> <IfModule !mod_authz_core.c> Order allow,deny </IfModule> </FilesMatch> # ----------------------------------------------------------------------------------------------- # 6. Override a few PHP settings that can't be changed at runtime (not required) # 500 NOTE: Try commenting out this entire section below if getting Apache 500 errors. # ----------------------------------------------------------------------------------------------- <IfModule mod_php5.c> php_flag magic_quotes_gpc off php_flag magic_quotes_sybase off php_flag register_globals off </IfModule> # ----------------------------------------------------------------------------------------------- # 7. Set default directory index files # ----------------------------------------------------------------------------------------------- DirectoryIndex index.php index.html index.htm # ----------------------------------------------------------------------------------------------- # 8. ProcessWire requires mod_rewrite # ----------------------------------------------------------------------------------------------- <IfModule mod_rewrite.c> RewriteEngine On AddDefaultCharset UTF-8 # ----------------------------------------------------------------------------------------------- # 9. If you only want to allow HTTPS, uncomment the RewriteCond and RewriteRule lines below. # ----------------------------------------------------------------------------------------------- # RewriteCond %{HTTPS} off # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # If using an AWS load balancer, use these two lines below instead of those above: # RewriteCond %{HTTP:X-Forwarded-Proto} =http # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # ----------------------------------------------------------------------------------------------- # 10. Set an environment variable so the installer can detect that mod_rewrite is active. # Note that some web hosts don't support this. If you get a 500 error, you might try # commenting out this SetEnv line below. # ----------------------------------------------------------------------------------------------- <IfModule mod_env.c> SetEnv HTTP_MOD_REWRITE On </IfModule> # ----------------------------------------------------------------------------------------------- # 11. OPTIONAL: Set a rewrite base if rewrites aren't working properly on your server. # And if your site directory starts with a "~" you will most likely have to use this. # ----------------------------------------------------------------------------------------------- # RewriteBase / # RewriteBase /pw/ # RewriteBase /~user/ # ----------------------------------------------------------------------------------------------- # 12. Access Restrictions: Keep web users out of dirs that begin with a period, # but let services like Lets Encrypt use the webroot authentication method. # ----------------------------------------------------------------------------------------------- RewriteRule "(^|/)\.(?!well-known)" - [F] # ----------------------------------------------------------------------------------------------- # 13. OPTIONAL: Redirect users to the 'www.' version of the site (uncomment to enable). # For example: http://processwire.com/ would be redirected to http://www.processwire.com/ # ----------------------------------------------------------------------------------------------- # RewriteCond %{HTTP_HOST} !^www\. [NC] # RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] # ----------------------------------------------------------------------------------------------- # 14. OPTIONAL: Send URLs with non-ASCII name-format characters to 404 page (optimization) # ----------------------------------------------------------------------------------------------- # RewriteCond %{REQUEST_URI} "[^-_.a-zA-Z0-9/~]" # RewriteCond %{REQUEST_FILENAME} !-f # RewriteCond %{REQUEST_FILENAME} !-d # RewriteRule ^(.*)$ index.php?it=/http404/ [L,QSA] # ----------------------------------------------------------------------------------------------- # 15. Access Restrictions: Protect ProcessWire system files # ----------------------------------------------------------------------------------------------- # Allow screenshot files (for install.php only: this 1 line below may be removed after install) RewriteCond %{REQUEST_URI} !(^|/)site-[^/]+/install/[^/]+\.(jpg|jpeg|png|gif)$ # Block access to any htaccess files RewriteCond %{REQUEST_URI} (^|/)\.htaccess$ [NC,OR] # Block access to protected assets directories RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets/(cache|logs|backups|sessions|config|install|tmp)($|/.*$) [OR] # Block acceess to the /site/install/ directory RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/install($|/.*$) [OR] # Block dirs in /site/assets/ dirs that start with a hyphen RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets.*/-.+/.* [OR] # Block access to /wire/config.php, /site/config.php, /site/config-dev.php, and /wire/index.config.php RewriteCond %{REQUEST_URI} (^|/)(wire|site|site-[^/]+)/(config|index\.config|config-dev)\.php$ [OR] # Block access to any PHP-based files in /templates-admin/ RewriteCond %{REQUEST_URI} (^|/)(wire|site|site-[^/]+)/templates-admin($|/|/.*\.(php|html?|tpl|inc))$ [OR] # Block access to any PHP or markup files in /site/templates/ RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/templates($|/|/.*\.(php|html?|tpl|inc))$ [OR] # Block access to any PHP files in /site/assets/ RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets($|/|/.*\.php)$ [OR] # Block access to any PHP files in core or core module directories RewriteCond %{REQUEST_URI} (^|/)wire/(core|modules)/.*\.(php|inc|tpl|module|info\.json)$ [OR] # Block access to any PHP files in /site/modules/ RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/modules/.*\.(php|inc|tpl|module|info\.json)$ [OR] # Block access to any software identifying txt files RewriteCond %{REQUEST_URI} (^|/)(COPYRIGHT|INSTALL|README|htaccess)\.(txt|md|textile)$ [OR] # Block all http access to the default/uninstalled site-default directory RewriteCond %{REQUEST_URI} (^|/)site-default/ # If any conditions above match, issue a 403 forbidden RewriteRule ^.*$ - [F,L] # PW-PAGENAME # ----------------------------------------------------------------------------------------------- # 16a. Ensure that the URL follows the name-format specification required by PW # See also directive 16b below, you should choose and use either 16a or 16b. # ----------------------------------------------------------------------------------------------- RewriteCond %{REQUEST_URI} "^/~?[-_.a-zA-Z0-9/]*$" # ----------------------------------------------------------------------------------------------- # 16b. Alternative name-format specification for UTF8 page name support. # If used, comment out section 16a above and uncomment the directive below. If you have updated # your $config->pageNameWhitelist make the characters below consistent with that. # ----------------------------------------------------------------------------------------------- # RewriteCond %{REQUEST_URI} "^/~?[-_./a-zA-Z0-9æåäßöüđжхцчшщюяàáâèéëêěìíïîõòóôøùúûůñçčćďĺľńňŕřšťýžабвгдеёзийклмнопрстуфыэęąśłżź]*$" # END-PW-PAGENAME # ----------------------------------------------------------------------------------------------- # 17. If the request is for a file or directory that physically exists on the server, # then don't give control to ProcessWire, and instead load the file # ----------------------------------------------------------------------------------------------- RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !(favicon\.ico|robots\.txt) # ----------------------------------------------------------------------------------------------- # 18. OPTIONAL: Prevent ProcessWire from attempting to serve images or anything in /site/assets/. # Both of these lines are optional, but can help to reduce server load. However, they # are not compatible with the $config->pagefileSecure option (if enabled) and they # may produce an Apache 404 rather than your regular 404. You may uncomment the two lines # below if you don't need to use the $config->pagefileSecure option. After uncommenting, test # a URL like domain.com/site/assets/files/test.jpg to make sure you are getting a 404 and not # your homepage. If getting your homepage, then either: do not use this option, or comment out # section #2 above that makes ProcessWire the 404 handler. # ----------------------------------------------------------------------------------------------- # RewriteCond %{REQUEST_FILENAME} !\.(jpg|jpeg|gif|png|ico)$ [NC] # RewriteCond %{REQUEST_FILENAME} !(^|/)site/assets/ # ----------------------------------------------------------------------------------------------- # 19. Pass control to ProcessWire if all the above directives allow us to this point. # For regular VirtualHosts (most installs) # ----------------------------------------------------------------------------------------------- RewriteRule ^(.*)$ index.php?it=$1 [L,QSA] # ----------------------------------------------------------------------------------------------- # 20. If using VirtualDocumentRoot (500 NOTE): comment out the one above and use this one instead # ----------------------------------------------------------------------------------------------- # RewriteRule ^(.*)$ /index.php?it=$1 [L,QSA] </IfModule> ################################################################################################# # END PROCESSWIRE HTACCESS DIRECTIVES ################################################################################################# # SP BEGIN php handler <IfModule mod_fcgid.c> AddHandler fcgid-script .php .php5 .php7 .phtml FcgidWrapper /usr/local/cpanel/cgi-sys/sp-ea-php56 .php FcgidWrapper /usr/local/cpanel/cgi-sys/sp-ea-php56 .php5 FcgidWrapper /usr/local/cpanel/cgi-sys/sp-ea-php56 .php7 FcgidWrapper /usr/local/cpanel/cgi-sys/sp-ea-php56 .phtml </IfModule> # SP END php handler
  20. Hi, I need to check the VAT number before the user make a registration. I start from here https://github.com/herdani/vat-validation, and this work well. But now I have to integrate this with the LoginRegister module, I'm not sure who do it, at moment I try to make the hook in this way: wire()->addHookAfter('LoginRegister::processRegisterForm', function ($event) { $form = $event->arguments[0]; $company = wire('input')->post->register_Iam; // check if you are a person or a company if ($company == '2') { // Get country code $options = wire('fieldtypes')->get('FieldtypeOptions')->getOptions(wire('fields')->get('shipping_countrycode')); foreach ($options as $value) { if(wire('input')->post->register_shipping_countrycode == $value->id) { $country_title = $value->title; $countryCode = substr($country_title, 0, 2); } } // Get VAT number $vatNumber = wire('input')->post->register_invoice_VAT; $check = new WireFileTools(); $check->include('vatValidation.class.php'); $vatValidation = new vatValidation( array('debug' => false)); $vatValidation->check($countryCode, $vatNumber); if ($vatValidation->isValid()) { return true; } else { $vatError = 'this VAT N° does not exist'; $vatNumber->error($vatError); } } }); I'm not sure but I think that everything works well until validation. How I can add the verification system? I feel like one of the problem is adding the vatValidation.class.php file in the hook. But I can't debug well this. I try to follow this post. Also I read the problem could be a namespace in the vatValidation.class file. But also, I'm not sure. vatValidation.class.php UPDATE I try also to use this $company = wire('input')->post->register_Iam; if ($company == '2'){ // Get country code $options = wire('fieldtypes')->get('FieldtypeOptions')->getOptions(wire('fields')->get('shipping_countrycode')); foreach ($options as $value) { if(wire('input')->post->register_shipping_countrycode == $value->id) { $country_title = $value->title; $countryCode = substr($country_title, 0, 2); } } // Get VAT number $vatNumber = wire('input')->post->register_invoice_VAT; function viesCheckVAT($countryCode, $vatNumber, $timeout = 30) { $response = array (); $pattern = '/<(%s).*?>([\s\S]*)<\/\1/'; $keys = array ( 'countryCode', 'vatNumber', 'requestDate', 'valid', 'name', 'address' ); $content = "<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'> <s11:Body> <tns1:checkVat xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'> <tns1:countryCode>%s</tns1:countryCode> <tns1:vatNumber>%s</tns1:vatNumber> </tns1:checkVat> </s11:Body> </s11:Envelope>"; $opts = array ( 'http' => array ( 'method' => 'POST', 'header' => "Content-Type: text/xml; charset=utf-8; SOAPAction: checkVatService", 'content' => sprintf ( $content, $countryCode, $vatNumber ), 'timeout' => $timeout ) ); $ctx = stream_context_create ( $opts ); $result = file_get_contents ( 'http://ec.europa.eu/taxation_customs/vies/services/checkVatService', false, $ctx ); if (preg_match ( sprintf ( $pattern, 'checkVatResponse' ), $result, $matches )) { foreach ( $keys as $key ) preg_match ( sprintf ( $pattern, $key ), $matches [2], $value ) && $response [$key] = $value [2]; } return $response; } $arr = viesCheckVAT($countryCode, $vatNumber); if ($arr[valid] == fasle) { ... } } This probably are better, but I'm not able to integrate with the validation of the module. ONE SOLUTION In the end I failed to make the hook as I wanted. So I thought I'd check the VAT before the module registered the user. Ok maybe it's not the best solution but it works. So, with the help of one person, we started from the PHP function I posted above, changing it this way: We sent a request via Ajax, this is activated when data is entered the input, this call via curl and returns a value that, following the logic in this case with a nice callback, enables or disables the send button ? <?php if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['task'] ) && $_POST['task']=='check' ){ ob_clean(); $result=null; function curl( $url=NULL, $options=NULL, $headers=false ){ /* Initialise curl request object */ $curl=curl_init(); /* Define standard options */ curl_setopt( $curl, CURLOPT_URL,trim( $url ) ); curl_setopt( $curl, CURLOPT_AUTOREFERER, true ); curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true ); curl_setopt( $curl, CURLOPT_FAILONERROR, true ); curl_setopt( $curl, CURLOPT_HEADER, false ); curl_setopt( $curl, CURLINFO_HEADER_OUT, false ); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true ); curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 20 ); curl_setopt( $curl, CURLOPT_TIMEOUT, 60 ); curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' ); curl_setopt( $curl, CURLOPT_MAXREDIRS, 10 ); curl_setopt( $curl, CURLOPT_ENCODING, '' ); /* Assign runtime parameters as options */ if( isset( $options ) && is_array( $options ) ){ foreach( $options as $param => $value ) curl_setopt( $curl, $param, $value ); } if( $headers && is_array( $headers ) ){ curl_setopt( $curl, CURLOPT_HTTPHEADER, $headers ); } /* Execute the request and store responses */ $res=(object)array( 'response' => curl_exec( $curl ), 'info' => (object)curl_getinfo( $curl ), 'errors' => curl_error( $curl ) ); curl_close( $curl ); return $res; } function checkvat( $code, $vatnumber, $timeout=30 ){ $url='http://ec.europa.eu/taxation_customs/vies/services/checkVatService'; $content = "<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'> <s11:Body> <tns1:checkVat xmlns:tns1='urn:ec.europa.eu:taxud:vies:services:checkVat:types'> <tns1:countryCode>%s</tns1:countryCode> <tns1:vatNumber>%s</tns1:vatNumber> </tns1:checkVat> </s11:Body> </s11:Envelope>"; $headers=array( 'Content-Type' => 'text/xml; charset=utf-8', 'SOAPAction' => 'checkVatService' ); $options=array( CURLOPT_POST => true, CURLOPT_POSTFIELDS => sprintf ( $content, $code, $vatnumber ) ); return curl( $url, $options, $headers ); } $code=$_POST['code']; $vatnumber=$_POST['vat']; /* check the VAT number etc */ $obj=checkvat( $code, $vatnumber ); /* if we received a valid response, process it */ if( $obj->info->http_code==200 ){ $dom=new DOMDocument; $dom->loadXML( $obj->response ); $reqdate=$dom->getElementsByTagName('requestDate')->item(0)->nodeValue; $valid=$dom->getElementsByTagName('valid')->item(0)->nodeValue; $address=$dom->getElementsByTagName('address')->item(0)->nodeValue; if ($valid == "true") { $result = "<p style='background-color: #fff;width: 30%;color:green;position: absolute;'>Valid Number</p>"; } else { $result = "<p style='background-color: #fff;width: 30%;color:red;position: absolute;'>Not Valid Number</p>"; } } exit( $result ); } ?> <script> const ajax=function( url, params, callback ){ let xhr=new XMLHttpRequest(); xhr.onload=function(){ if( this.status==200 && this.readyState==4 )callback( this.response ) }; xhr.open( 'POST', url, true ); xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ); xhr.send( buildparams( params ) ); }; const buildparams=function(p){/* construct payload/querystring from object */ if( p && typeof( p )==='object' ){ p=Object.keys( p ).map(function( k ){ return typeof( p[ k ] )=='object' ? buildparams( p[ k ] ) : [ encodeURIComponent( k ), encodeURIComponent( p[ k ] ) ].join('=') }).join('&'); } return p; }; document.addEventListener('DOMContentLoaded', ()=>{ let form = document.getElementById('LoginRegisterForm'); form.register_invoice_IVA_VAT.addEventListener('keyup', e=>{ let url=location.href; let params={ 'task':'check', 'vat': form.register_invoice_IVA_VAT.value, 'code':'IT' /*need to hook the select filed because now return the ID number*/ }; let callback=function(r){ let vatF = document.getElementById('register_invoice_IVA_VAT'); var thisreturn = r.includes("Not"); var divNew = document.createElement("div"); divNew.innerHTML = r; if (thisreturn == false) { vatF.classList.add('success'); vatF.classList.remove('error'); document.getElementById("register_submit").disabled = false; document.getElementById('wrap_register_invoice_IVA_VAT').appendChild(divNew); } else { vatF.classList.add('error'); vatF.classList.remove('success'); document.getElementById("register_submit").disabled = true; document.getElementById('wrap_register_invoice_IVA_VAT').appendChild(divNew); } } ajax.call( this, url, params, callback ); }) }); </script> So, I didn't make the hard coding part to be complete honest I ask in stackoverflow here, but anyway I want also add this post here if anyone in this form needed it, it can be a starting point. (Maybe could be a interesting features for the new Padloper or some ecosystm module @kongondo)
  21. I try to separate the requests for a template file (html) and the data / json and searching for a way to do it without enable url segments for each template (or enable by hook / api runtime). I'll build a autoload module and the request routing should be done there to send a template / view / html file OR execute the "controller" (page / PW template file) without the need of a switch case / if else inside of the page template file... Any idea how to do it? UrlSegments would work with for example first segment "template" or "view" to request the html file, but would be nice to do it without the use of segments (maybe needed for other things and default disabled). Any PW API way to do it by request content type, urlSegment / QueryString or anything else hook? Or a special "api" page which use urlSegments, load the page given by urlSegment and verify request type (html or json) by compare page path with (loaded page path)?
  22. you could assign a runtime parameter to them, see this topic for an example: https://processwire.com/talk/topic/10920-remove-duplicates-in-a-foreach-loop-but-count-them/?p=102592 notice how this assigns a count as a runtime parameter: $i->useCount = count($pages->find("interests=$i"));
  23. I only used the module FieldtypeRuntimeMarkup for now and it works, but has one big disadvantage (which maybe not applicable to all users): You can not use the runtime markup fields in a ListerPro to sort because PW is looking for a database table and throws an error.
  24. You could make use of http://modules.processwire.com/modules/process-admin-actions/ and build a custom action that lets you choose a Page Table field and then a page to add to that field. Or you could use http://modules.processwire.com/modules/fieldtype-runtime-markup/ and build a page selector field just above or below the Page Table field and on pag save, process the selected page and add it to the PT field. You could also hook into InputfieldPageTable::render and add the page selector interface there. Lots of options really ?
  25. The application is BE only , no frontend . I added more or less just a land list whith many columns that i added. I never expected such an impact. Debug mode has almost no impact 30 ms. Tracy is installed , but i could need some hints how to use it to track those bottlenecks. The only hook added just composes a field from several others. No repeaters added . Concerning to ProDevTools The hook whith the biggest runtime was Tracy whith about 200 ms ? Turning it of made the page significantly faster. Still page isn't really responsive but most time intensitive hook now takes 13 ms Rendering of /site/templates/admin.php still takes about 220 ms. After Installing and adding modules it was about 60-80 ms which i feel is still very much as Applications like Dadabik come whith a rendering time of about 10 ms on this server. Ok turning tracy back on for further testing. Concerning to tracy Selector Queries (11) none of them took more than 1 ms The PDO queries do not show how long they took... Is there a way to show this ? Php Memmory limit is 128M Peak of allocated memory 23.01 MB PHP is 7.1.2 PW is 3.0.120 In general it would be interesting what the factors are that slow down PW and why. Modules installed ? Number of Templates/Fields.? Number of Pages? And even on really high powered server i never had a rendering time below 50 ms, feels kind of strange to me.
×
×
  • Create New...