Jump to content

Kiwi Chris

  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Kiwi Chris

  1. Has anyone else managed to get ProcessWire working on Azure App service with PHP 8.x? App Service runs a Docker container, but the container image has been changed from Apache to Nginx between PHP 7.x and 8.x so of course .htaccess files don't work. I've followed instructions here: https://www.schakko.de/2021/09/08/deploying-php-8-0-applications-with-azure-app-service/ and tried to convert the ProcessWire .htaccess file here: https://winginx.com/en/htaccess but the best I've been able to get was the home page loading, but all other pages just give a 404 error. My client is a non-profit and want to use Azure because they get free hosting under Microsoft's non-profit programme, so before I give up, has anyone else managed to get this working?
  2. I didn't have anything in the migrate file to install the module, but I did have code to create a lot of fields and templates and create some pages which all got created. I wanted these to be under the control of migrations, but assumed (incorrectly) migrations would only run on installed modules, ie once the module is installed I do want the migrations file watched and run if there are any changes, but if the module isn't yet installed it doesn't make sense to run its migrations. An easy way to get it to work the way I want is to do a conditional check at the start of the migrations file to see if the module is installed or not, and only run the actual migration code to create fields and templates if the module is installed. That way I won't get a bunch of fields and templates installed for an inactive module.
  3. I'm not sure whether it's intentional or not, but I started experimenting with deploying a site setup to a clean, blank copy of ProcessWire with RockMigrations I dumped a copy of RockMigrations and a custom module with a migration file in the format MyModule/MyModule.migrate.php I installed RockMigrations via the admin UI, and was wondering why it was taking so long. Afterwards I checked, and found it had gone ahead and installed all the modules, fields, files, and created pages in the custom module's migrate file, even though the module itself was not yet installed. I'm not sure whether that's intended behaviour? If it is, I need to make sure I don't upload a module with a migrate file unless I want the migration to run as soon as I upload it. My assumption was that RockMigrations would start watching and running migrations in a module's directory once the module is installed, but possibly I assumed wrong. Apart from being surprised that the module's migration file ran before the module was installed, it was very nice to see a whole app with multiple fields, templates, modules, and pages constructed before my eyes, and it's way more modular than exporting site profiles, since I can build a base functionality in one migration file and then add components in others.
  4. Something like this could work. There are two possible scenarios I can think of. A site profile migration or a module migration. In either case, it's still necessary to be able to manually specify the order of the fields and templates because of possible dependency issues, but it should be possible to generate the field and template definitions (for those who want to, rather than coding them).
  5. That's a significant issue, and I tend to think it's better to have migrations generated manually rather than fully automated, but I think possibly more automation is possible. Here's my first ever migrations file, that works nicely for me. //Modules $rm->installModule( "FieldtypeLeafletMapMarker", "https://github.com/madebymats/FieldtypeLeafletMapMarker/archive/PW3.zip" ); //Fields include __DIR__ . '/fields/fields.php'; //Templates include __DIR__ . '/templates/Discipline.php'; include __DIR__ . '/templates/Member.php'; include __DIR__ . '/templates/Show.php'; include __DIR__ . '/templates/ProductionRole.php'; //Web Templates //include __DIR__ . '/templates/contact.php'; include __DIR__ . '/templates/ProductionRole.php'; include __DIR__ . '/templates/location.php'; include __DIR__ . '/templates/pastShows.php'; $rm->createPage('Website', 'website', 'basic-page', 'home'); $website = $this->wire->pages->get('name=website'); $rm->createPage('Past Shows', 'past-shows', 'pastShows', $website); $rm->createPage('About Us', 'about-us', 'basic-page', $website); $rm->createPage('Contact', 'contact', 'location', $website); In each of those template definitions, I have: $rm->createTemplate('...'); $rm->setTemplateData( ... ); I did combine the field definitions into one file, but I could have done them individually. I still have full manual control over the order of migrations, but my migrations file itself is pretty small, and each template definition file is self-contained, and I think it makes the code cleaner. It's not as efficient maybe as running $rm->migrate with all the templates in one big array but it works, and I can control the order. It made me think, if I'm using this sort of structure, then the getCode method of RockMigrations, instead of being used just to display the code on screen, could build the definition files for me. A way to have some manual control if definitions are combined in a file would be to have some sort of Migrations build file for a module, which specifies the fields and templates in the order that they need to be processed. In my module migrations file, I've specified the order manually, but I've kept the definitions separate. The way I'm using this is in association with modules, so I wonder whether the way to do it is to hook into the module UI, check whether the module has a migrations build file, and if it does, offer a button to generate the module migration based on the specification in the build file?
  6. This is perfect. I've thought of an enhancement to RockMigrations that would be useful because I'm lazy. In the showCopyCode method, instead of copying and pasting, an additional option would be an 'export' button, and a path field. I'd still need to write a migration file, as the order of field and template migrations is important, but if I simply list the fields and templates as includes in order, then it would make the migration file more concise, and I could still trigger a migration by updating version details of file, but without having to keep copying and pasting into a file. eg, if I want the definition for myTextField to be associated with ProcessHelloWorldModule, then I could set a path site/modules/ProcessHelloWorldModule/fields/ and dump the definition there by button click. I've been having a play and here's a mockup although it doesn't do anything yet. I'm not sure whether it actually needs its own save button, or whether to hook into saving the field and save the RockMigrations code to the path specified. I've never worked with modifying field/template editing before, so I'm not sure how to persist the save path. Of course I can do this manually, by copying and pasting each field and template definition into its own file but I think this might be a time saver for people who like to use the UI, but also want to use migrations.
  7. A quick question before I go ahead and set up migrations files: I like using the ProcessWire UI to edit my field and template properties, and RockMigrations gives me all the code to copy and paste into a migrations file, so this is nice and easy, but I want to make sure on my development instance that I don't accidentally overwrite field or template definitions by triggering a migration when I've yet to copy and paste updates from those fields into the migrations file. I do want the migrations to run automatically on the deployed site I think though, as the migrations file(s) will only get updated on the deployed site when they're ready to run. I think I'd prefer to include the migrations in page classes, as that keeps all the definitions of an object in one place and nice and modular, just I don't want to accidentally trigger these on my local development environment before I have all the fields and templates modified with any changes I've done via the UI. What's the best way to handle this scenario?
  8. ProcessWire does and doesn't do this. You initially have to edit your HTML templates to define the structure of pages on your website, but after this, all the editing of the content can be done either on the front-end or back-end without having to edit HTML directly. Most other CMSs do the same, just some come with a lot of predefined themes to get you up and going where someone else has created the HTML templates. Both the strength and weakness of ProcessWire is that it doesn't come with a lot of predefined themes. That's because ProcessWire doesn't try to decide for you how your site should be structured, and third-party themes for other CMSs typically depend on the CMS having a specific structure to data. That might seem like a good idea, until the moment you try to do something that doesn't fit the assumptions the CMS has made about how data should be structured, then it turns into a nightmare to try to make it do something different. ProcessWire makes virtually no assumptions about your data, which is why it requires some knowledge of HTML to make templates to start with, but it's much easier to change than other CMSs, and once you've got your HTML templates, it's very easy to edit content without needing to know anything about HTML, and is arguably more intuitive for editing content than some other CMSs that involve some clunky and inconsistent plugins and add-ons to do anything beyond the basics. I guess you could use the analogy, ProcessWire is a box of Lego bricks. You've got to do some construction, limited only by your imagination. Other CMSs are like a ready made toy. If it's the toy you want, then they're quicker and easier, but if you got a toy car, and really wanted a helicopter, then trying to change it is going to be hard. With ProcessWire it can be a car or a helicopter, but you've got to build it.
  9. I think this could work both ways. One of the things I really like is that it's possible to use the admin UI to design your fields and pages, but RockMigrations then gives you the code generated to copy and paste into your migrations file. If you start prototyping using the UI, and intended to add it to a migration but forgot to, having an indication that a field or template isn't included in a migration is just as useful as indicating that it is. This would be particularly useful when adding RockMigrations to an existing site, as it makes it easier to see quickly what has been see up to be managed by migrations and what hasn't been.
  10. Something like? $database->exec('ALTER TABLE pages AUTO_INCREMENT = 1');
  11. This looks great. I'd been considering building something similar myself as I have a need for it. I do have a need for it to integrate with an existing site, but from the looks of the latest Rock Migrations, there's an easy way to get the configuration of fields and templates to paste them into a migrations file, and that's something else I've been meaning to have a play with, so I might set up a local version of this profile, install Rock Migrations, and see if I can build a migration that allows me to apply this to an existing site.
  12. @kixe Your fork of the module doesn't allow issue reports on Github, so I'll mention it here. There is a hook into AdminRestrictBranch module if present to automatically restrict the page tree to the root of the domain in multisite mode. if ($this->wire('modules')->isInstalled('AdminRestrictBranch')) { if (method_exists('AdminRestrictBranch', '___getBranchRootParentId')) { $this->addHookAfter('AdminRestrictBranch::getBranchRootParentId', function ($e) { $e->return = $this->rootPageID; }); } else $this->warning('AdminRestrictBranch::getBranchRootParentId() is not hookable'); } Where this has an issue is that if a user is only supposed to have access to page tree belonging to domain A as defined in AdminRestrictBranch, and then logs in to domain B, the branch restriction defined in their user profile or role is overridden by the hook in multisite. This means if any user knows other domains under the same installation of ProcessWire using Multisite, they can log in and access the page tree of those domains, even if AdminRestrictBranch is configured to otherwise prevent them from accessing them. A quick fix is to comment out the hook code. A better fix would be to check whether a user or role already has branch restrictions in place defined by AdminRestrictBranch, and if so, defer to those restrictions, but if not, provide default behaviour as exists of restricting to the root of the domain.
  13. Oops! Sorry @adrian I just realised I got my module mentions back to front. I'm using your 'official' version of AdminRestrictBranch, and the Multisite version by @kixe There does seem to be some interaction going on between them that's causing unexpected results. It's not necessarily a fault with AdminRestrictBranch, it looks like an issue with Multisite module as it hooks AdminRestrictBranch::getBranchRootParentId , but it's still worth mentioning here in case someone else runs into the same problem, so that they're aware of potential issues using the two modules together. I found an easy fix was just to comment out the hook code in the Multisite Module.
  14. I'm not sure whether it's an issue with the current version of the core (3.0.203), or some other interaction, but currently I'm getting a weird issue. All users, regardless of what branch they're restricted to, are being restricted to the same branch. ie branch restriction is happening, but regardless of what branch is specified, they all get the same branch. [edit] I seem to have found the source of the problem. It is an interaction between Multisite module and @kixe version ofAdminRestrictBranch. What seems to be happening, is that when a user logs in, they will get the full page tree of whatever domain they have logged in under, regardless of how AdminRestrictBranch is configured. In some ways that's desirable: log in under a domain, and only get that domain's page tree, but it's also a security issue, as if a user knows another domain in the same multisite setup, and logs in with the login that's supposedly restricted to the page tree for another domain, they can see the page tree of the other domain.
  15. Thanks for sharing an interesting use of comments. I think I would find the hook code useful as I have FormBuilder and I can think of scenarios where I could use this. As a matter of interest, if you want to aggregate meta data from all comments and get an average rating for a given piece of meta data, what's the most efficient way to achieve this?
  16. The ProFields Combo field and Table fields create SQL tables behind the scenes, but they're still fieldtypes, so are expected to be added to a ProcessWire template and are linked to the page tree. Sometimes that's not necessary or desirable. With regards to creating custom tables, I'm quite happy writing SQL statements for this, or using the generated CREATE TABLE statements with a database export from mySQL, or for that matter even other dialects of SQL, with a bit of editing if necessary. It's not hard to write a CREATE TABLE statement initially, then an ALTER TABLE statement if subsequent changes are needed. I think this would play nice with your RockMigrations module to generate SQL schema changes in code, and I don't want to turn ProcessWire into mySQLAdmin or Adminer which is installed with Tracy Debugger, but it would be nice to have an end user friendly UI to view and edit custom SQL tables in the ProcessWire admin. You have made me thing of something I hadn't considered, about how to migrate SQL listers and editing forms, if the InputField settings or fields to display in a lister change, but if they're accessible via the API, it should be possible to manage migrations in a similar way to ProcessWire native fields and templates.
  17. @ryanFieldtypeCombo comes pretty close, but like you say, you define the table structure with the fieldtype. Also as a fieldtype it needs to be associated with a template, that links into the ProcessWire page tree, which isn't always desirable with SQL tables from an existing database. I'm thinking there would probably need to be two configurable Process modules. An ProcessSQLLister and ProcessSQLForm module. Names are just suggestions ProcessSQLTemplate could be another option however as it's not an output template, it's an admin UI for editing arbitrary SQL data. ProcessSQLLister would be similar to Lister Pro, except for selecting a source, you'd select an SQL table, then choose what fields from the table to display in the lister. Dealing with lookup fields which are similar to page reference fields, but can refer to an arbitrary database table would probably be the biggest challenge, but the basic lister should be pretty straightforward. Edit functionality would depend on a related ProcessSQLForm being defined for the specified table. ProcessSQLForm would involve picking an SQL table, then selecting fields from the table to include on the form in the order desired, and mapping and configuring a sane InputField type depending on the SQL field type. @kixe has already made FieldtypeSelectExtOption which can handle lookups from arbitrary SQL tables, so that InputField should be able to handle relational reference fields, and core InputFields should be able to map to other SQL fields types. For both, access control at the table level would be desirable. While access control at the field level would be technically possible, I don't think it's necessary at least initially, especially if it adds complication since the fields are SQL fields rather than ProcessWire fields. I can try to mock something up, but if someone else beats me to it, then feel free to go ahead. I think ProcessWire has all the nuts and bolts to do this, it's just a case of putting them together.
  18. There weren't very many CMS/CMF platforms either. I started out with SSIs to start reducing redundancy and duplication, then ended up starting my own CMS around 2000, but I picked a loser in terms of development language, and I realised trying to maintain a CMS for a modest number of clients on my own wasn't really efficient use of time. Someone introduced me to ProcessWire in 2015, and since then nearly all my websites have been converted to it. Web development and database development have progressed together for me, so ProcessWire's separation of content and presentation, and strong access control are critical for me. I evaluated my other CMS platforms before I settled on ProcessWire and I simply didn't like them as they either had a steep learning curve or were too output focused or both. I wouldn't use Word to try to build a relational database, nor would I use WordPress. I think if there is one major thing still on my wish list, it would be the ability to have a UI using ProcessWire inputfields to create data entry forms for arbitrary SQL tables. A common scenario for me is converting offline databases (often Microsoft Access) to cloud based alternatives. Usually it's possible to restructure everything within ProcessWire's pages model, but sometimes I just want to be able to dump the data across and build a UI quickly with no need for data to exist within a page model. I've been playing around a bit looking at building module(s). I'd love the goodness of Lister/(Pro), but instead of picking a template, pick an arbitrary SQL table and specify fields from it, set access control etc in the same way Lister Pro woks, and then have I guess what I'd call an SQLTemplate where you'd pick an arbitrary SQL table, select fields from it, and for each one specify an inputfield, within the contraints of the SQL field type. Of course none of this data would be accessible within ProcessWire's page structure out of the box, however there's already $database->query() to execute an arbitrary SQL query and return a result set, so using arbitrary SQL data within templates is already easy, so the only bit missing is a UI to manage arbitrary SQL tables as easily as ProcessWire pages in admin, but it's already halfway there with inputfields that don't care where their data comes from.
  19. There is an optional module in the core ProcessForgotPassword that you can install to enable people to reset their passwords if they forget. With regard to preventing even super-user role from changing any password other than their own, I think it could be done, but would require a hook in site/ready.php I'd imagine adding a hook before InputfieldPassword::processInput should be able to check the current user, and if they're not the same user as the password belongs to, then abandon any changes. I may not have the right hook method. A hook before Pages::save might be another option, as everything including users are 'pages' in Processwire, so the logic would be something like if($user->name != $page->name && $page->template == 'user'){ //Prevent page saving. } Someone else can probably help give a working example, or if I get time I can have a try and update my post once I've got something working.
  20. In case anyone else finds it helpful, I've been having major issues with both the original deprecated and later version of the module described in this thread not working properly with the latest builds of ProcessWire (>=3.0.200) and it seems like this module hasn't had much love in a long time, but after poking around on Github, I found a fork by @kixe that works for me. https://github.com/kixe/Multisite/blob/master/Multisite.module
  21. Interesting discussion, and I'll add a rather ironic perspective. I inherited a largely non-functional website project that someone else had built in Craft, about 3 years ago, and at the time I found the Craft documentation wasn't particularly clear, whereas I worked out how to use ProcessWire after about 20 minutes of reading the documentation. I converted the whole project to ProcessWire, and actually got the project functional. I had to write several custom modules and deal with a lot of hooks and set up CRON jobs to interact with a third party API, and I found ProcessWire a pleasure to work with. That said, I can understand that there are pain points for some people with ProcessWire, and it's always good to look at other systems to see how they do things in case there's something useful that could be incorporated into ProcessWire. My personal preference other than ProcessWire is Umbraco, which is built on ASP.Net rather than PHP, but in many respects is similar, so I don't have a problem jumping between PHP for ProcessWire and Razor syntax and C# for Umbraco. It also is an open source project, but with commercial add-ons like a form builder (which makes ProcessWire FormBuilder look cheap). Now that .Net and SQL Server run on Linux, it's potentially even more appealing to me, although ProcessWire is still my first choice. Currently I'm a solo developer, but as my workload grows, and also clients are starting to ask for an insurance policy in case something happens to me, the potential to be able to manage collaboration on projects is something that's increasingly on my mind, and out of the box, this isn't something that ProcessWire handles, although there are third party solutions like RockMigrations by@bernhard
  22. It is possible to use pre-built themes with ProcessWire, but since you can't be sure in advance what fields someone will create, rather than building a ProcessWire specific theme, any well documented HTML theme should be easy to adapt to ProcessWire with not much effort. Mostly I think people build sites from scratch, but I did have someone once who wanted to use a theme, and had a limited budget, so it was actually quicker and cheaper to adapt an off-the-shelf HTML theme for them than build from scratch.
  23. How about something like this? This way your editor can recognise the HTML tags as well as the PHP tags. The <?= ?> tag is a PHP shorthand for echo ... that you can insert within HTML. For PHP logic you need the full <?php ... ?> tag. You'll notice I've left a couple of echo statements in because they're short, and it's not really worth closing the PHP tag and opening another one for such short sections of HTML code. <div class="row mb-2"> <?php $items = $pages->find("homepage_item=1"); foreach($items as $item) { // $item === $pages->get($item->id); ?> <div class='col-md-6'> <div class='row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative'> <div class='col p-4 d-flex flex-column position-static'> <h3 class='mb-0'><?= $item->title?></h3> <?php if($item->arbitrary_publish_date) { echo "<div class='mb-1 text-muted'>$item->arbitrary_publish_date</div>"; } else { echo "<div class='mb-1 text-muted'></div>"; } ?> <p class='card-text mb-auto'><?= $item->summary ?></p> <a href='<?= $item->url ?>' class='stretched-link'>Continue reading</a> </div> <div class='col-auto d-none d-lg-block'> <svg class='bd-placeholder-img' width='200' height='250' xmlns='http://www.w3.org/2000/svg' role='img' aria-label='Placeholder: Thumbnail' preserveAspectRatio='xMidYMid slice' focusable='false'><title>Placeholder</title><rect width='100%' height='100%' fill='#55595c'/><text x='50%' y='50%' fill='#eceeef' dy='.3em'>Check it out!</text></svg> </div> </div> </div> <?php // echo $item->title; } ?> </div>
  24. That's exactly how migrations files work with Entity Framework in .Net, but you've got to write that manually. I'm OK with that as it's not much to write. For new, changed, or deleted fields, it builds the migration automatically from the current definition of system state based on what's changed. That's exactly what I'd want. The main situation in ProcessWire where tracking data can be useful is with pages used as input for list items. I think I want both; a full description of system state that can be used to install a new instance of a given configuration, but also migrations so that an existing installation can be synchronised with a specific state. Maybe it's not the best approach, but that's similar to how Entity Framework on .Net works, and I work with that as well, so having a similar workflow to something I'm already using would keep things simple, but I understand there may be other solutions that are more efficient for other people. One of the key points for me as well, is I want to be able to do this at the module level, in addition to or instead of the site level.
  25. Some people are wanting continuous upgrades to complete sites, but the kind of scenario I'm facing for the first time, is potentially identical, simultaneous upgrades required to multiple sites with different data, but on an extensible modular level. I've been thinking along the lines of having a method to build a full state, but whenever any objects in that state change, having some way to track what's changed since the last build. Building the full state looks to be relatively easy; specify what fields, templates, and pages are required, and in what order to satisfy dependencies, and then dump JSON files with definitions of all the objects required. Handling changes since the initial build in a reversible way is more of a challenge. I think if I did want reproducible upgrades to whole sites, that would be easily achievable by simply specifying the module dependencies in a configuration file, as they would encapsulate all the fields, templates, and pages required for a given site configuration, I'm moving towards the idea that everything other than the core would basically end up being a module, which in some cases may be responsible for nothing more than maintaining a set of fields templates, and possibly pages (eg for lists) for a specific task. Existing module dependency capabilities mean I can handle if a module depends on existing fields, as I can simply make it depend on the module that installs and maintains those fields. EG, module 1 installs a base set of fields, templates and pages. Module 2 requires some of the object data installed by module 1 but extends on that with additional functionality including its own fields, templates, and possibly pages. Module 3 also requires data from module 1 and extends on it in a different way. All sites will have module 1, but will have either module 2 or 3 but not both. I don't want or need to migrate an entire site, as that would get too messy if I start deploying a number of similar sites, but each with unique user data and sub-components. I still want to be able to use the UI though for rapid prototyping, and then build a deployment configuration once I've tested things out. Obviously changing things via the UI doesn't automatically add dependencies to a module, but that's fairly insignificant to achieve. Microsoft's Entity Framework Core specifically has an issue with this. It can generate automatic migrations with schema changes, but a renamed field or class results in a drop and create, rather than a rename, and their documentation recommends manually editing auto-generated migrations to deal with this. Obviously this problem isn't unique to ProcessWire by any means. ? The way things work there, is class definitions are complete, self-contained defintions of the schema, but separate migration files handle getting to that state if the current schema doesn't match the class definitions. Although .Net is a different platform, I wonder whether the way Entity Framework handles migrations could provide some insight into how to build a workable system for ProcessWire?
  • Create New...