Leaderboard
Popular Content
Showing content with the highest reputation on 08/04/2023 in all areas
-
This week on the core dev branch is ProcessWire 3.0.224! Relative to 3.0.223 it has 25 commits and 17 issue resolutions (see dev branch commit log). I think we are within 1-2 weeks of having the new main/master version, so I'll be looking closely for any new reports. Consider us now in a dev branch feature lockdown in preparation for the main/master version. At this stage, there likely won't be any new features added or issue resolutions that would require significant field testing (at least not until the merge to main/master). If you have a chance to test the current dev branch version, please do, and let us know if you run into any issues. Thanks and have a great weekend!11 points
-
4 points
-
http://shift-up.pt/ Shift-Up is a consultancy company from Portugal that specializes in government incentives and financing. This is my first project using ProFields and RockFrontend, and I can't really believe how long it took me to start using both. Profields' InputMatrix is a huge step up from my previous custom module that I hacked together using file selects and custom field visibility. And RockFrontend, just by getting latte in the mix, makes everything a lot more polished and professional. The project is a fresh start from the previous old Wordpress solution they had, taking care as to not harm the SEO standing this site had built up with all its content. I started out by writing a content import script that took hundreds of pages from the oh so messy WP export and turned them into neat PW pages. I also had to handle the URLs in the process, ensuring that the old unstructured WP links would be fed to the Redirects module. So the focus here was more on carrying over the content without having to rewrite everything, and now that we're here, when new programs come up we have a platform that can properly grow and add new layout solutions and features.2 points
-
Hello, I was originally going to include this as part of my forthcoming AdminStyleChroma module but decided to roll it out as its own module. https://github.com/solonmedia/ImageColorThief Please check out the readme for a deeper explanation - but the short version here for now: This module adds two new methods to the Pageimage class, allowing you to extract the main dominant color or a palette of prevalent colors from an image. You can use the entire image to evaluate color dominance, or you can use a select swatch from the image based on inset rectangles from the edges, blocks at each corner, or a swatch centered on the focus point if you choose to use it. You can also select the granularity of the quantization to get more accurate color results. This is not an eyedropper algorithm - the colors are close approximates. Great if you have color schemes you'd like to coordinate with the headliner or seasonal images, or if you'd like to be able to sort a gallery of images by dominant color, etc. Looks real nice, for example if you are running a ken burns style image fade background and the images are sorted by a channel, etc. How to sort them? Ugh that's something I haven't tackled - yet: https://www.alanzucconi.com/2015/09/30/colour-sorting/ It works on JPG, GIF, PNG and WEBP images. It outputs RGB, HEX, RGB Integer, raw Array with R, G, B elements or an object. Once I've got myself registered and whatnot I'll submit it to the Modules Directory. Installs from zip for now: https://github.com/solonmedia/ImageColorThief/archive/refs/heads/main.zip I'd consider it Beta - the underlying libraries are pretty stable but I'd like to run a few more tests on input. Let me know if you have any questions/thoughts.2 points
-
Since classes/HomePage.php is part of the default site profile (blank profile) for recent ProcessWire versions, this makes it sound like the site might've been updated and possibly reinstalled. Would be interesting to know what those new files in wire were, e.g. if they were also files added by an update. Same goes for those new files in root dir as well. The site shouldn't update on its own, of course, so that still doesn't explain what might've happened in the first place. Your site didn't have install.php available, by any chance? That, combined with write permission for the web server user, could be one potential gotcha. This sounds like something that @ryan might want to look into, just in case. With the information we currently have available it is not possible to figure out much more.2 points
-
This module allows you to integrate hCaptcha bot / spam protection into ProcessWire forms. hCaptcha is a great alternative to Google ReCaptcha, especially if you are in the EU and need to comply with privacy regulations. The development of this module is sponsored by schwarzdesign. The module is built as an Inputfield, allowing you to integrate it into any ProcessWire form you want. It's primarily intended for frontend forms and can be added to Form Builder forms for automatic spam protection. There's a step-by-step guide for adding the hCaptcha widget to Form Builder forms in the README, as well as instructions for API usage. Features Inputfield that displays an hCaptcha widget in ProcessWire forms. The inputfield verifies the hCaptcha response upon submission, and adds a field error if it is invalid. All hCaptcha configuration options for the widget (theme, display size etc) can be changed through the inputfield configuration, as well as programmatically. hCaptcha script options can be changed through a hook. Error messages can be translated through ProcessWire's site translations. hCaptcha secret keys and site-keys can be set for each individual inputfield or globally in your config.php. Error codes and failures are logged to help you find configuration errors. Please check the README for setup instructions. Links Github Repository and documentation InputfieldHCaptcha in the module directory Screenshots (configuration) Screenshots (hCaptcha widget)1 point
-
Session Info Lists information about active sessions in a similar way to SessionHandlerDB, but for file-based sessions. Only install the module if you are not already using SessionHandlerDB. Installation 1. If you want to be able to see the pages that are being viewed by active sessions then set... $config->sessionHistory = 1; ...in /site/config.php If you have already set $config->sessionHistory to a higher number then you can leave it unchanged: 1 is the minimum needed for use in the Session Info module. 2. Install the Session Info module. A helper module named "Session Extras" will be automatically installed also. 3. If you want to be able to see the IP address and/or user agent for active sessions then visit the module config page for Session Extras and tick the relevant checkboxes. 4. You can now view information about active sessions at Access > Sessions. Screenshots With $config->sessionHistory set to 1 or higher: Additional information is listed when IP address and user agent tracking are enabled in Session Extras: https://github.com/Toutouwai/ProcessSessionInfo https://processwire.com/modules/process-session-info/1 point
-
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 Screenshots1 point
-
The KKP.LAW site has been a Site of the Week in Processwire Weekly in the past. For this reason I would like to share some insights. So I hope someone will get an inspiration and maybe others may provide idees how to improve my process. Development Setup Currently I build my projects with DDEV and upload them to the server using Github Actions. This way I can view and develop them locally and push them to live when I am done. I also have SCSS which I write to a src folder and is watched by DDEV and also by the GitHub action. So it is possible to change SCSS via a browser in GitHub and everything will be deployed automatically. The basics The KKP.LAW was the last project before I develop this orocess with modules. But the basics are almost the same. Years ago I used Typo3 for building websites. But the really complex update routine, the complicated configuration and the ongoing change how you should build templates made it necessary for me to look for a new CMS. So Wordpress was never an option and many others were also very complicated, so I looked at ProcessWire. After a second look I really understood the approach and built my first websites with Processwire. Very quickly I switched from Typo3 to Processwire. Implementing new features into existing websites was so easy with it. But one thing I really liked in Typo3 was the concept of pages and page content. On each page you can have multiple page contents. I.e. text or images or a mix of both. So I started to rebuild this logic in Processwire. I have templates for pages and templates for page contents. I use a page and pagecontent tag for the different types. On the PHP templates I just need to include them. So each page collects its page content children. All page contents can have a wrapper with some css classes. So it is easy to create layouts with this system. CSS Framework For this I use a kind of own CSS framework which is much more individual than big ones like Bootstrap. Personally I like the concept of 10 columns. So I have a 10 + 4 + 3 column system. Paddings are always added inside a column. So I dont need rows. All page content is inside a div tag with display: flex; flex-wrap: wrap;. The result is very clean and I get a slim file sizes. Components Later I changed the page content more into components. They are not as powerful as in modern JavaScript framework. It was more a logical step for me. In my eyes, the massive classes I would need to build responsive websites always displeased me. So more and more I changed my approach to design and configure everything in a component with maybe one or two classes and do the rest in CSS. But in some cases the old approach is still good. Current approach So I made some modules for my basic needs. The current module is very personal build arrount my needs and my DDEV configuration. Each component (or page content) has its own module. So it has some methods, PHP template and basic scss which I bind into my deployment process. I wrote a bash script that sets up ddev, installs Processwire and these modules. Also creates a GitHub brunch with the required action that can be synced into a live server. - So this is a basic overview of my approach. Hope it is an inspiration for you. Questions and suggestions are very welcome. See Website: KKP.LAW My own website: (also Processwire) Jens Weigel – Büro für Design1 point
-
Hei, I'm wondering how easy it is to get support from someone in a Nordic country. Not that being in the Nordics is required, but it would be my first attempt.1 point
-
My word I love this so much. Thank you ??1 point
-
But actuals logs, stack and software version plus taking note of all files timestamp before doing any modif should be the minimum to help here.1 point
-
1 point
-
I will run a full-text search on the whole website for some strings mostly targeting http headers and creating files, and also hidden timestamp files apparently logging the last activity. Most of the strings are Unicode encoded though. For sure everything is backed up so if anyone would like to look into it, let me know.1 point
-
Give us a screenshot and list those files, please, so we can check AND please download the whole directory and archive it in case someone wants to look into it further.1 point
-
Had a similar issue a while back because I used this: 'Content-Type': 'application/json', Just switched the content type and it started working: 'Content-Type': 'application/x-www-form-urlencoded',1 point
-
Interesting! And you’re certain it’s not your hosting that has in fact been compromised? Be it your login details to access cPanel or similar, or if you are on shared hosting that they’ve not managed to exploit a vulnerability on that side of things? You could ask your hosting provider if there is anything interesting in your access logs etc. Do you have forms on your website and if so, are they sanitising the data? Is there any old modules or JavaScript libraries? Is ProcessWire up to date? I’m no security expert, but these would the key areas I would be asking questions about that come to mind right off the bat.1 point
-
For noobs like me that needs a ";" on the end. when you get an "unexpected } on line 17". But thank you it's tremendously helpful having these examples.1 point
-
1 point
-
Glad to hear it, thanks for the kind of words., do not hesitate to try Duplicator integration in wire-cli. To get back to the topic, understood, then you should be able to get started quickly, With both web3 you will get users/guest wallet connected. To interact with Ethereum and smart-contracts, the easier way is to use one of the cleanest API made by Alchemy through their alchemy-sdk. You will be able with something like ten lines of code to get the tokens (fungible or not) from the contract(s) of your choices and then send ajax request to your scripts/templates to set something in the user session and let user view the hiddens pages and/or medias. Do you use a "vanilla" JS/PHP frontend or are you on React, Svelte or something?1 point
-
The module is ready to be used (and is already used in several sites from several devs), just the site to sell it and also docs are not yet done. I'm working hard on that front. It will be 49€ for a single site for early birds. If anyone needs a copy already just write me a PM. Or signup for Rock-Monthly to get notified when I officially release it ? https://www.baumrock.com/rock-monthly/1 point
-
I've seen a couple of questions regarding namespaces and autoloading floating around the forum recently, so I decided to write a little tutorial. In general, I often see people getting confused when they try to wrap their head around namespaces, autoloading, Composer and the mapping of namespaces to directory structures all at once. In fact, those are very much independent, distinct concepts, and it is much easier to explain and understand them separately. So this guide is structured as follows: How namespaces work in PHP. How autoloading works in PHP. Conventions for mapping namespaces to directory structures: PSR-4. How autoloading works in Composer and ProcessWire's class loader. How to use the class loader in a ProcessWire module. Feel free to skip the sections you're already familiar with. Namespaces in PHP The purpose of namespaces in PHP is to avoid naming conflicts between classes, functions and constants, especially when you're using external libraries and frameworks. Nothing more. It's important to understand that this has nothing at all to do with autoloading, directory structures or file names. You can put namespaced stuff everywhere you want. You can even have multiple namespaces inside a single file (don't try this at home). Namespaces only exist to be able to use a generic name – for example, ProcessWire's Config class – multiple times in different contexts without getting a naming conflict. Without namespaces, I couldn't use any library that includes a Config class of it's own, because that name is already taken. With namespaces, you can have a distinction between the classes ProcessWire\Config and MoritzLost\Config. You can also use sub-namespaces to further segregate your code into logical groups. For example, I can have two classes MoritzLost\Frontend\Config and MoritzLost\Backend\Config– a class name only needs to be unique within it's namespace. You can declare the namespace for a PHP file using the namespace statement at the top: // file-one.php <?php namespace ProcessWire; // file-two.php <?php namespace MoritzLost\Frontend; This way, all classes, methods and constants defined inside this file are placed in that namespace. All ProcessWire classes live in the ProcessWire namespace. Now to use one of those classes – for example, to instantiate it – you have a couple of options. You can either use it's fully qualified class name or import it into the current namespace. Also, if you are inside a namespaced file, any reference to a class is relative to that namespace. Unless it starts with a backward slash, in this case it's relative to the global namespace. So all of those examples are equivalent: // example-one.php <?php namespace ProcessWire; $page = new Page(); // example-two.php <?php use ProcessWire\Page; $page = new Page(); // example-three.php <?php $page = new ProcessWire\Page(); // example-four.php <?php namespace MoritzLost\Somewhere\Over\The\Rainbow; $page = new \ProcessWire\Page(); The use statement in the second example can be read like this: “Inside this file, all references to Page refer to the class \ProcessWire\Page” How autoloading works Every PHP program starts with one entry file – for ProcessWire, that's usually it's index.php. But you don't want to keep all your code in one file, that would get out of hand quickly. Once you start to split your code into several individual files however, you have to take care of manually including them with require or include calls. That becomes very tedious as well. The purpose of autoloading is to be able to add new code in new files without having to import them manually. This, again, has nothing to do with namespaces, not even something with file locations. Autoloading is a pretty simple concept: If you try to use a class that hasn't been loaded yet, PHP calls upon it's registered autoloaders as a last-ditch attempt to load them before throwing an exception. Let's look at a simple example: // classes.php <?php class A { /** class stuff */ } class B { /** class stuff */ } // index.php <?php spl_autoload_register(function ($class) { include_once 'classes.php'; }); new A(); new B(); This is a complete and functional autoloader. If you don't believe me, go ahead and save those two files (classes.php and index.php) and run the index.php with php -f index.php. Then comment out the include_once call and run it again, then you'll get an error that class A was not found. Now here's what happens when index.php is executed (with the autoloader active): Our anonymous function is added to the autoload queue through spl_autoload_register. PHP tries to instantiate class A, but can't because it's not loaded yet. If there was no autoloader registered, the program would die with a fatal error at this point. But since there is an autoloader ... The autoloader is called. Our autoloader includes classes.php with the class definition. That was a close one! Since the class has been loaded, execution goes back to the index.php which can now proceed to instantiate A and B. If the class was still not loaded at this point, PHP would go back to the original plan and die. One thing to note is that the autoloader will only be called once in this example. That's because both A and B are in the same file and that file is included during the first call to the autoloader. Autoloading works on files, not on classes! The important takeaway is that PHP doesn't know if the autoloader knows where to find the class it asks for or, if there are multiple autoloader, which one can load it. PHP just calls each registered autoloader in turn and checks if the class has been loaded after each one. If the class still isn't loaded after the last autoloader is done, it's error time. What the autoloader actually does is pretty much wild wild west as well. It takes the name of the class PHP is trying to load as an argument, but it doesn't have to do anything with it. Our autoloader ignores it entirely. Instead, it just includes classes.php and says to itself “My job here is done”. If class A was in another file, it wouldn't have worked. This process has two main advantages: Since autoloaders are only called on-demand to load classes just in time, we only include the files we actually need. If in the example above class A and B are not used in some scenarios, the classes.php will not be included, which will result in better performance for larger projects (though this isn't as cut and dry, since autoloading has it's own overhead, so if you load most classes anyway during a single request, it will actually be less efficient). If the autoloader is smart enough to somehow map class names to the files they're located in, we can just let the autoloader handle including the classes we need, without having to worry about jamming include statements everywhere. That brings us to ... PSR-4, namespaces and directory structures As you see, namespaces and autoloading are both pretty limited concepts. And they aren't inherently linked to each other. You can namespace your classes without ever adding an autoloader, and you can autoload classes that are all in the same namespace. But they become useful when you put them together. At the core of all that autoloading talk is a simple idea: By putting classes in files named after their class names, and putting those files in directory hierarchies based on the namespace hierarchy, the autoloader can efficiently find and load those files based on the namespace. All it needs is a list of root namespaces with their corresponding directories. The exact way class names and namespaces are mapped to directory structures and file names is purely conventional. The accepted convention for this is PSR-4. This is a super simple standard which basically just sums up the ideas above: A base namespace is mapped to a specific directory in the file system. When the autoloader is asked to load a class in that namespace (or a sub-namespace of it), it starts looking in that folder. This "base" namespace may include multiple parts – for example, I could use MoritzLost\MyAwesomeLibrary as a base and map that to my source directory. PSR-4 calls this a "namespace prefix". Each sub-namespace corresponds to a sub-directory. So by looking at the namespace, you can follow subdirectories to the location where you expect to find the class file. Finally, the class name is mapped directly to the file name. So MyCoolClass needs to be put inside MyCoolClass.php. This all sounds simple and straightforward - and it absolutely is! It's only once you mash everything together, mix up language features, accepted conventions and proprietary implementations like Composer on top that it becomes hard to grasp in one go. Composer and ProcessWire's class loader Now all that's left is to talk about how Composer and ProcessWire provide autoloading. Composer, of course, is primarily a tool for dependency management. But because most libraries use namespaces and most developers want to have the libraries they're using autoloaded, those topics become a prerequisite to understanding what Composer does in this regard. Composer can use different autoloading mechanisms; for example, you can just give it a static list of files to include for every request, or use the older PSR-0 standard. But most modern libraries use PSR-4 to autoload classes. So all Composer needs to function is a mapping of namespace prefixes to directories. Each library maintains this mapping for it's PSR-4-structured classes through the autoload information in their composer.json. You can do this for your own site to: Just include the autoload information as shown in the documentation and point it to the directory of your class files. Composer collects all that information and uses it to generate a custom file at vendor/autoload.php — that's the one you need to include somewhere whenever you set up Composer in one of your projects. Bells and whistles aside, this file just registers an autoloader function that will use all the information collected from your own and your included libraries' composer.json to locate and include class files on demand. You can read more about how to optimize Composer's autoloader for production usage here. If you want to read up on how to set up Composer for your own sites, read my ProcessWire + Composer integration guide instead. And finally, what does ProcessWire do to handle all this? Turns out, ProcessWire has it's own autoloader implementation that is more or less PSR-4 compliant. You can access it as an API variable ($classLoader or wire('classLoader'), depending on context). Instead of using a static configuration file like Composer, the namespace -> directory mapping is added during the runtime by calling $classLoader->addNamespace. As you would expect, this function accepts a namespace and a directory path. You can use this to register your own custom namespaces. Alternatively, if you have site-specific classes within the ProcessWire namespace, you can just add their location to the class loader using the same method: $classLoader->addNamespace('ProcessWire', '/path/to/your/classes/'). Utilizing custom namespaces and autoloading in ProcessWire modules Now as a final remark, I wanted to give an example of how to use custom namespaces and the class loader in your own modules. I'll use my TrelloWire module as an example: Decide what namespace you're going to use. The main module file should live in the ProcessWire namespace, but if you have other classes in your module, they can and should use a custom namespace to avoid collisions with other modules. TrelloWire uses ProcessWire\TrelloWire, but you can also use something outside the ProcessWire namespace. You need to make sure to add the namespace to the class loader as early as possible. If either you or a user of your module tries to instantiate one of your custom classes before that, it will fail. Good places to start are the constructor of your main module file, or their init or ready methods. Here's a complete example. The module uses only one custom namespaced class: ProcessWire\TrelloWire\TrelloWireApi, located in the src/ directory of the module. But with this setup, I can add more classes whenever I need without having to modify anything else. /** * The constructor registers the TrelloWire namespace used by this module. */ public function __construct() { $namespace = 'ProcessWire\\TrelloWire'; $classLoader = $this->wire('classLoader'); if (!$classLoader->hasNamespace($namespace)) { $srcPath = $this->wire('config')->paths->get($this) . 'src/'; $classLoader->addNamespace($namespace, $srcPath); } } Source Thanks for making it through to the very end! I gotta learn to keep those things short. Anyway, I hope this clears up some questions about namespaces and autoloading. Let me know if I got something wrong, and feel free to add your own tips and tricks!1 point