Leaderboard
Popular Content
Showing content with the highest reputation on 07/29/2025 in Posts
-
RockGatekeeper A lightweight ProcessWire module that provides simple password protection for your website using a configurable gatekeeper password. Overview RockGatekeeper adds a basic authentication layer to your ProcessWire site. When enabled, it blocks access to all pages for guest users unless they provide the correct password via URL parameter. Features Minimal footprint: Only runs when gatekeeper is configured Session-based: Once authenticated, users stay logged in for the session IP tracking: Remembers the IP address of authenticated users Clean URLs: Automatically removes the password parameter from URLs after authentication CLI safe: Won't interfere with command-line operations Installation Copy the RockGatekeeper folder to your site/modules/ directory Install the module in ProcessWire admin Configure the gatekeeper password in your site config Configuration Add the gatekeeper password to your site configuration: // In site/config.php $config->gatekeeper = 'your-secret-password'; Usage Basic Authentication To access the protected site, users need to append the password as a URL parameter: https://yoursite.com/?gatekeeper=your-secret-password After successful authentication, users will be redirected to the same page without the password parameter, and they'll have access to the entire site for the duration of their session. Download & Docs: baumrock.com/RockGatekeeper4 points
-
Just add an extension here: $files->setTargetFilename($user->name."-avatar"); Although I might agree that PW should perhaps be able to handle it regardless. But also, why not use the field? user()->of(false); user()->avatar->deleteAll(); $field_avatar = user()->getInputfield('avatar'); $field_avatar->setMaxFilesize(500_000); $field_avatar->processInput(input()->post); if (!user()->save(['quiet'=>true])) die('oh no'); user()->of(true);2 points
-
@bernhard Sounds good! To add to the greater conversation, here's how a .env file approach would work. A .env file is created for your local development. A .env file is created on a staging server if one is used. A .env file is created for the production server. Each file exists where they will be used and the values match the requirements for the application to run in that location. Since the .env file for a project is not committed to the repository, a commonly adopted way to document what is needed in it is to create a .env.example file that contains all of the variables used by the application without values. This is unrelated to @bernhard's reply but I didn't share some ProcessWire specific information in my original post that readers- whether choosing to use .env or not- may want to keep in mind. .env files are part of a secrets management strategy. Sensitive values should be stored in a separate location, like a password manager. The config.php file is a sensitive document. ProcessWire provides direction on securing the file on your server, however this doesn't account for workflows like Git or sharing config.php in collaborative situations. Sensitive values committed to a repository (even if it's private) must be considered compromised. It's not just about DB credentials. Here's an example: /** * Installer: User Authentication Salt * * This value was randomly generated for your system on 2023/02/22. * This should be kept as private as a password and never stored in the database. * Must be retained if you migrate your site from one server to another. * Do not change this value, or user passwords will no longer work. * */ $config->userAuthSalt = "c187bd9fx935ca861f43da592475fe6afa20a63"; Ryan's note says "private as a password", and that's real. Your auth salt must remain the same regardless of where your code is being run so it is a universally sensitive secret whether local, staging, or production. This unique value is part of how ProcessWire hashes passwords in the database. Having a config.php file committed in a repo with this value means that your site/app is now insecure. Removing it from your repo and pushing the change will not make it secure since it's in the commit history. So now you're faced with the situation of storing that value in addition to your database credentials which change depending on where your site/app is running. That's makes a case for a .env file or a secure solution like @bernhard is developing for his workflow implementation.1 point
-
I wasn't sure if this module would be of much general interest but Teppo has mentioned it a couple of times in recent issues of PW Weekly so I'm adding it to the modules directory and creating a support topic for it. Page Action: Include File A generic action for Lister Pro allowing the selection of a PHP file containing the action code. This can be useful for quickly applying API processing to pages without going to the trouble of creating a custom Page Action module for the purpose. Large quantities of pages can be processed thanks to Lister Pro's feature that splits the pages into chunks. Usage The module creates a folder at /site/templates/PageActionIncludeFile/ on install. Place your PHP files inside this folder. Within each file, the $item variable refers to the page that is currently being processed. There is no need to save the page within your code because Lister Pro does this automatically. Example action file: append_foo_to_page_title.php <?php namespace ProcessWire; /** @var Page $item */ // Append " foo" to page title $item->title .= " foo"; Enable the PageActionIncludeFile action in the config of one or more Lister Pro instances. In the Lister Pro instance, set the filters or select the pages as needed and then choose the "Include File" action. Use the select field to choose a file you have added to /site/templates/PageActionIncludeFile/. Click "Execute" to apply the action. https://github.com/Toutouwai/PageActionIncludeFile https://processwire.com/modules/page-action-include-file/1 point
-
Thanks @Robin S I love tools like this as often there is no need to do the same task again in the future.1 point
-
@markus-th I had this on my list, but somehow didn't get to doing it. Yes, it should be an easy fix.1 point
-
1 point
-
@Sanyaissues and I have been working intensively on a new version of RockMigrations Deployments, which will be moved to RockShell and will support Github Environments. So we thought about having an .env file per environment instead of prefixing every variable: // STAGING.env dbHost=localhost dbName=db_staging dbUser=whatever dbPass=1234 vs STAGING_dbHost=localhost STAGING_dbName=db_staging STAGING_dbUser=whatever STAGING_dbPass=1234 PRODUCTION_dbHost=localhost PRODUCTION_dbName=db_production PRODUCTION_dbUser=whatever PRODUCTION_dbPass=1234 But at the moment I decided to go with PHP files, so there is no need to change anything in your library π Thx for the explanation!1 point
-
@bernhard Glad you found it useful! Yes. The logic behind .env files is that they are tied to the environment/server, not the application, so 1 environment = 1 .env file. Think of it as the store of values necessary for your application to run in a given environment. Your application doesn't have to care where it's being run, it just knows that the necessary values will be provided and everything works. It would overwrite the cached file since the Env utility follows the general single-file usage of .env files Out of curiosity, how would multiple .env files be useful?1 point
-
With the talk of a new master in this post its worth mentioning mobile admin needs some work still. Great progress all around though.1 point
-
v7.0.0 removes the hideFromGuests() feature and moves it to the dedicated RockGatekeeper module:1 point
-
1 point
-
Hey @FireWire this is a really cool class! @Sanyaissues recommended it, so I had a closer look. I added it to RockShell (experimental) here: https://github.com/baumrock/RockShell/tree/env And I have added this little improvement: https://github.com/baumrock/RockShell/blob/7605dcaad6f0b009e01039405936aad825dc47c5/Env/Env.php#L37-L39 Then I added this test command: https://github.com/baumrock/RockShell/blob/env/App/Commands/EnvTest.php What I do not understand: It creates the file RockShell/Env/cache/env.php to cache the results. Does that mean that your class only supports reading from one single .env file system wide? What if I loaded another .env file from another folder? Would that be cached somewhere else or would that overwrite my existing .env file? Or is it maybe the point to always ever only have one .env file for the project? Never used .env before, sorry π1 point
-
I've been working with ProcessWire for a while now, and I've noticed that using Composer to manage dependencies and autoload external libraries isn't as prevalent in ProcessWire development as in other areas of PHP programming. I started out by using the default setup recommend in this blogpost. However, one major problem I have with this approach is that all external dependencies live in the webroot (the directory the server points to), which is unfavourable from a security standpoint and, in my opinion, just feels a bit messy. In this tutorial, I want to go through a quick setup of Composer and ProcessWire that keeps the dependencies, all custom-written code and other source material outside of the webroot, and makes full usage of the Composer autoloader. This setup is pretty basic, so this tutorial is probably more useful to beginners (this is why I'll also include some general information on Composer), but hopefully everyone can take something away from this for their personal workflow. Site structure after setup This is what the directory structure can look like after the setup: . βββ composer.json βββ composer.lock βββ node_modules β βββ ... βββ public β βββ index.php β βββ site β βββ wire β βββ ... βββ packacke-lock.json βββ package.json βββ sass β βββ main.scss β βββ _variables.scss β βββ ... βββ src β βββ ContentBag.php β βββ ... βββ vendor βββ autoload.php βββ composer βββ league βββ symfony βββ ... As mentioned, the main point of this setup is to keep all external libraries, all other custom source code and resources out of the webroot. That includes Composer's vendor folder, your node_modules and JavaScript source folder if you are compiling JavaScript with webpack or something similar and including external scripts via NPM, or your CSS preprocessor files if you are using SASS or LESS. In this setup, the public directory acts as the webroot (the directory that is used as the entry point by the server, DocumentRoot in the Apache configuration). So all other files and directories in the mysite folder aren't accessible over the web, even if something goes wrong. One caveat of this setup is that it's not possible to install ProcessWire modules through Composer using the PW Module Installer (see Blogpost above), but that's just a minor inconvenience in my experience. Installation You'll need to have composer installed on your system for this. Installation guides can be found on getcomposer.org. First, open up your shell and navigate to the mysite folder. $ cd /path/to/mysite/ Now, we'll initialize a new Composer project: $ composer init The CLI will ask some questions about your projects. Some hints if you are unsure how to answer the prompts: Package names are in the format <vendor>/<project>, where vendor is your developer handle. I use my Github account, so I'll put moritzlost/mysite (all lowercase). Project type is project if you are creating a website. Author should be in the format Name <email>. Minimum Stability: I prefer stable, this way you only get stable versions of dependencies. License will be proprietary unless you plan on sharing your code under a FOSS license. Answer no to the interactive dependencies prompts. This creates the composer.json file, which will be used to keep track of your dependencies. For now, you only need to run the composer install command to initialize the vendor directory and the autoloader: $ composer install Now it's time to download and install ProcessWire into the public directory: $ git clone https://github.com/processwire/processwire public If you don't use git, you can also download ProcessWire manually. I like to clean up the directory after that: $ cd public $ rm -r .git .gitattributes .gitignore CONTRIBUTING.md LICENSE.TXT README.md Now, setup your development server to point to the /path/to/mysite/public/ directory (mind the public/ at the end!) and install ProcessWire normally. Including & using the autoloader With ProcessWire installed, we need to include the composer autoloader. If you check ProcessWire's index.php file, you'll see that it tries to include the autoloader if present. However, this assumes the vendor folder is inside the webroot, so it won't work in our case. One good place to include the autoloader is using a site hook file. We need the autoloader as early as possible, so we'll use init.php: EDIT: As @horst pointed out, it's much better to put this code inside the config.php file instead, as the autoloader will be included much earlier: // public/site/config.php <?php namespace Processwire; require '../../vendor/autoload.php'; The following also doesn't apply when including the autoloader in the config-file. This has one caveat: Since this file is executed by ProcessWire after all modules had their init methods called, the autoloader will not be available in those. I haven't come across a case where I needed it this early so far; however, if you really need to include the autoloader earlier than that, you could just edit the lines in the index.php file linked above to include the correct autoloader path. In this case, make sure not to overwrite this when you update the core! Now we can finally include external libraries and use them in our code without hassle! I'll give you an example. For one project, I needed to parse URLs and check some properties of the path, host et c. I could use parse_url, however that has a couple of downsides (specifically, it doesn't throw exceptions, but just fails silently). Since I didn't want to write a huge error-prone regex myself, I looked for a package that would help me out. I decided to use this URI parser, since it's included in the PHP League directory, which generally stands for high quality. First, install the dependency (from the project root, the folder your composer.json file lives in): $ composer require league/uri-parser This will download the package into your vendor directory and refresh the autoloader. Now you can just use the package in your own code, and composer will autoload the required class files: // public/site/templates/basic-page.php <?php namespace Processwire; use \League\Uri\Parser; // ... if ($url = $page->get('url')) { $parser = new Parser(); $parsed_url = $parser->parse($url); // do stuff with $parsed_url ... } Wiring up custom classes and code Another topic that I find really useful but often gets overlooked in Composer tutorials is the ability to wire up your own namespace to a folder. So if you want to write some object-oriented code outside of your template files, this gives you an easy way to autoload those using Composer as well. If you look at the tree above, you'll see there's a src/ directory inside the project root, and a ContentBag.php file inside. I want to connect classes in this directory with a custom namespace to be able to have them autoloaded when I use them in my templates. To do this, you need to edit your composer.json file: { "name": "moritzlost/mysite", "type": "project", "license": "proprietary", "authors": [ { "name": "Moritz L'Hoest", "email": "info@herebedragons.world" } ], "minimum-stability": "stable", "require": {}, "autoload": { "psr-4": { "MoritzLost\\MySite\\": "src/" } } } Most of this stuff was added during initialization, for now take note of the autoload information. The syntax is a bit tricky, since you have to escape the namespace seperator (backslash) with another backslash (see the documentation for more information). Also note the PSR-4 key, since that's the standard I use to namespace my classes. The line "MoritzLost\\MySite\\": "src/" tells Composer to look for classes under the namespace \MoritzLost\MySite\ in the src/ directory in my project root. After adding the autoload information, you have to tell composer to refresh the autoloader information: $ composer dump-autoload Now I'm ready to use my classes in my templates. So, if I have this file: // src/ContentBag.php <?php namespace MoritzLost\MySite; class ContentBag { // class stuff } I can now use the ContentBag class freely in my templates without having to include those files manually: // public/site/templates/home.php <?php namespace Processwire; use MoritzLost\MySite\ContentBag; $contentbag = new ContentBag(); // do stuff with contentbag ... Awesome! By the way, in PSR-4, sub-namespaces correspond to folders, so I can put the class MoritzLost\MySite\Stuff\SomeStuff in src/Stuff/SomeStuff.php and it will get autoloaded as well. If you have a lot of classes, you can group them this way. Conclusion With this setup, you are following secure practices and have much flexibility over what you want to include in your project. For example, you can just as well initialize a JavaScript project by typing npm init in the project root. You can also start tracking the source code of your project inside your src/ directory independently of the ProcessWire installation. All in all, you have good seperation of concerns between ProcessWire, external dependencies, your templates and your OOP-code, as well as another level of security should your Server or CGI-handler ever go AWOL. You can also build upon this approach. For example, it's good practice to keep credentials for your database outside the webroot. So you could modify the public/site/config.php file to include a config or .env file in your project root and read the database credentials from there. Anyway, that's the setup I came up with. I'm sure it's not perfect yet; also this tutorial is probably missing some information or isn't detailed enough in some areas depending on your level of experience. Feel free to ask for clarification, and to point out the things I got wrong. I like to learn as well ? Thanks for making it all the way to the bottom. Cheers!1 point
-
@MoritzLost regarding earliest include of the autoloader, I think the site config.php is the right place. It is parsed / executed before modules, but it get not overwritten with core updates. ?1 point
-
Just to clarify the bit about "putting stuff outside the webroot" for security reasons: This is certainly a nice precaution, but processwire is not using it because there are way to many shared hosters, where it's simply not possible to go outside the webroot. I'd also say that if your webserver is not behaving correctly you've got bigger problems to deal with, so usually just adjusting your .htaccess file should be perfectly fine as well. Especially as your php process still needs to be able to read things even if they're not within the webroot to be able to execute them. There's not really a need for composer for that part as processwire has it's own psr-4 compatible classloader: https://processwire.com/api/ref/class-loader/1 point