Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Posts posted by flydev

  1. Hi @protro

    But does it work even if you upload the site manually? I am asking that because as the path is written in the body field raw data in the db, with or without duplicator, image paths should be corrupted in any way.

    As example and based on your setup, the data of a body field with an image should look - on dev and prod - something similar to (can you confirm ?) :

    <p>Sagittis turpis ad habitasse risus lorem phasellus platea imperdiet aenean, platea porta adipiscing dapibus velit eros purus malesuada laoreet vestibulum</p>
    <p><img src="/my-site/site/assets/files/1/44849-the-image-2016.897x0-is.jpg" alt="" width="897" /></p>


  2. Hi, it seem a server issue, but for now we cant see what is the root source of the disk being filled.

    Do get an access to ssh again, which is the most important thing for now, you could use à logged user, and then in the admin, delete all logs file, then SSH asap. Once in the server, check /var/log and remove some old *.gz or the bigger to get more space, then investigate.

    Try to make a backup or an image of the server if you can before doing root cmd.


    • Like 2
  3. @James Morris I had fixed it in on the feature-encryption branch, I will need to finish the feature and merge it, but meanwhile, can you try this version and let me know and confirm ?

    there: https://github.com/flydev-fr/Duplicator/tree/feature-encryption

    direct-dl: https://github.com/flydev-fr/Duplicator/archive/refs/heads/feature-encryption.zip


    Edit: @James Morris please try instead the dev branch, It is based on the latest v1.5.1 and contain the S3 fixes.

    dev branch: https://github.com/flydev-fr/Duplicator/tree/dev

    direct download: https://github.com/flydev-fr/Duplicator/archive/refs/heads/dev.zip

  4. 8 hours ago, adrian said:

    Note the missing PORT from the variables in #1 and also the duplication of ${DATABASE} in #3a

    Yes I saw that, but it was in the commented line so I didn't fixed it instantly, will push the fix.


    8 hours ago, adrian said:

    Actually, the only other suggestion is to make it a real initial value for the textarea rather than a placeholder, because I actually had to go and open mysqldump.unix.sh to get a starting script I could then edit.

    Ok I see, in first instance I had in mind to put a button to get the template script copied in the clipboard in order to paste and modify it. I will push also the fix following your recommendation 👍


    I was also thinking of pushing a new feature that would allow you to export and import module settings on other installations, what do you think, it could help? 

    • Like 1
  5. @adrian with v1.5.1 you can write your dump script in the custom shell script config field like that:


    # Custom Remote Dump
    # (1) Set up all the mysqldump variables
    # Fix trailing slash in cache path if needed
    # (2) in case you run this more than once a day, remove the previous version of the file
    unalias rm     2> /dev/null
    rm ${FILE}     2> /dev/null
    rm ${FILE}.zip  2> /dev/null
    # (3) do the mysql database backup dump (remote)
    mysqldump --opt --protocol=TCP --user=${USER} --password=${PASS} --host=${DBSERVER} --port=${PORT} ${DATABASE} > ${OUTPUT}

    You can of course also set hardcoded values.

    • Like 1
  6. Hi, sorry for the delay guys.

    @adrian I made it configurable, it should also check for carriage return when a custom script is given, please check releases/tag/v1.5.0 and tell me if you need something more.

    Edit2: Rereading your post again, I just realized that I omitted a detail... it'll be ok on v1.5.1 sorry.


    @Boost Thanks 🙂 . You can check if mysqldump is avail. on the config page. And if needed, to be sure that mysqldump is found, you could run some tests, also make sure - with Duplicator 1.4.29 - that the binary zip is available. Duplicator v1.5.0 show you this information on the module configuration page, with some more friendly exec return code error when the script run (see link at the end of this post).

    Some suggestions/debug steps if needed:

    1. is mysql in env path and runnable? with normal user type `mysqldump` and `zip`
    2. if #1 is ok, try with user/group assigned to your web server, eg. with www-data:
      sudo su www-data -s /bin/sh
    3. For `mysqldump` only - grab the dump script there and adjust variables in order to make a test
      1. cd /path/to/site/assets/cache
      2. sudo wget https://raw.githubusercontent.com/flydev-fr/Duplicator/v1.5.0/scripts/mysqldump.unix.sh
      3. sudo nano ./mysqldump.unix.sh and set correct or dummy values (or with vim, etc..)
      4. sudo chown www-data:www-data ./mysqldump.unix.sh
      5. sudo su www-data -s /bin/sh
      6. chmod +x ./mysqldump.unix.sh
      7. run a test: ./mysqldump.unix.sh

    Anyway, you should grab the last version I just release before messing with it, because if the issue is that zip isn't available, it will fallback using WireZipFile. 

    Edit: Just a word, I got this issue and it was zip that was missing (about exit code 2).


    • Like 2
  7. Hi @protro

    Rainbowkit is a really good package but last time I checked it (some months ago) I could see that it's built on wagmi, which is only working with React and then didn't paid so much attention to it as I am only coding on Svelte. Recently I saw popped a port of wagmi on svelte but still not tested it.

    FYI, the inertia module linked miss a little update, and the samples provided you will found are deprecated and are built using webpack. Did you have some experience with JS libs or frameworks (I mean vue, react or svelte) ? If not, I suggest you to start on Svelte as it's really the easier and natural frameworks to start on without experience.

    Anyway, as you said it, links above will helps you for sure. With any app sample you can find, you just have to send an ajax request to your ProcessWire page/template to get an answer with the required api keys/tokens/ whatever you need. Example:

    // 1. create a template called `web3` with a text field called `apikey` 
    // 2. create php template in `site/web3.php` and leave it empty with no code
    // 3. create a page called `web3` with template `web3`
    // 4. in `init.php` write:
    // this function will help you to fight CORS issue between your app and pw site
    function cors() {
      // Allow from any origin
      if (isset($_SERVER['HTTP_ORIGIN'])) {
          // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
          // you want to allow, and if so:
          header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
          header('Access-Control-Allow-Credentials: true');
          header('Access-Control-Max-Age: 86400');    // cache for 1 day
      // Access-Control headers are received during OPTIONS requests
      if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
              // may also be using PUT, PATCH, HEAD etc
              header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
              header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
     * Example of a simple router using ProcessWire's built-in URL hook system.
     * By appending /json to any page URL, you'll get a JSON representation of the page
     * Require ProcessWire 3.0.173 or newer.
     * see: https://processwire.com/blog/posts/pw-3.0.173/#outputting-json-data-about-any-page-when-the-last-part-of-the-url-is-json
     * Note that this is a very simple example. For more advanced routing, you might want to
     * use a Process module like AppApi made by @mauricio.
    $wire->addHook('(/.*)/json', function($event) {
      $page = $event->pages->findOne($event->arguments(1));
      // fight cors (for test purpose only)
      if($page->viewable()) return [
        'id' => $page->id,
        'url' => $page->url,
        'title' => $page->title,
        'apikey' => $page->apikey
    // from any javascript lib or framework, send a request and get an answer
    const response = await fetch("https://localhost.local/web3/json");
    const data = await response.json();
    console.log(data); // <-- contain json answer
      id: 1000,
      url: "https://mywebsite.local/web3",
      title: "web3 page",
      apikey: "API-ABCD-0123"

    I've fallen behind on the vite and inertia module release, but it's coming, it's a matter of days, I suggest you to wait for it and try the web3 sample coming.


    • Like 1
  8. Hi and welcome @ryangorley 👋

    1. give a read to:




    2. refer to #1

    3. the very first one tool you and the team need while working with ProcessWire is:





    - keep an eye on @Robin S gems (modules) handy on every situation:


    - subscribe to weekly.pw

    - and do not hesitate to search and use the forum, even for "i will feel dumb" questions.

    Enjoy 😄 

    • Like 3
  9. Yes, and I misread your post, I didn’t paid attention that the site is served from MAMP through prepos proxy.

    And as you already spot, they are transformed in your bundle source. Keep in mind that all process calls are Node.js things and aren’t available in the browser. 

    Anyway, on the example of Alchemy, the api key is made for you, what I mean is, the front app make a request to ProcessWire endpoint, then the needed requests are made from ProcessWire to alchemy endpoint using your api key stored on server side, eg. in template or module, db, .env file/process, then Alchemy answer your server, and finally, ProcessWire send back the response to the front app.

    It seem you got the idea. What is complicated on your side, if I can help?

    If is just to test and see external services like alchemy from local, just do not scratch your head to much, and use them as they are, included in the bundle. Using env variable on this case make things easier than going into the source code to change them.


    • Thanks 1
  10. @protro nice tool, I think I am going to build something similar but based with vite/rollup.

    About your issue, as you pointed it, your are serving your website from MAMP server, then the env will not be available on built app when served by MAMP and you will need to use a solution like php dotenv, and I saw you already read the thread about dotenv then I assume you got it working ?

    It's also worth noting that by using prepros you are bundling your app with webpack and not vite or rollup, keep in mind that when you will head to js libs documentation or when trying to find what's is not working.

    Under the hood, there is the stack list:

    Webpack 5.86.0
    Babel 7.22.5
    Autoprefixer 10.4.14
    Node Sass 9.0.0
    PostCSS 8.4.24
    PostCSS Preset 8.4.2
    Dart Sass 1.63.3
    Tailwindcss 3.3.2
    Terser 5.17.7


    On 8/10/2023 at 10:11 PM, protro said:

    dependencies being bundled ?

    Yes. Or to be more precise, what we can call Entry points. It contain the entry point of your app and the vendors. For more information about the splitting process head to webpack doc.

    • Like 1
  11. @strandoo without brainstorming a lot, you could setup an hidden pre-filled field. You certainly want to use `processLoginForm()` and optionnaly `loginSuccess()` hooks. Example there on this old thread, feel free to ask for help:



    Edit: I highly suggest you to buy a license for the Pro version if your project can afford it, the module is safe, but when dealing with secure access, you want something maintained. You will have possibility to ask ryan directly, and it's a way of "sponsoring" Ryan dev, without speaking of the benefit to the community.

       👆  ... comes from the company’s Managing Director (you want to keep a good reputation 😁)

    That was my positive comment of the day 🙂

    • Like 1
  12. To users of TailwindCSS / Windy, I think you will want to use UnoCSS.

    @MarkE just see your thread about your page builder, to avoid workarounds or hacks, you don't want to use interpolated or concatened strings. 

    <div class="<?= $error ? 'text-red-600' : 'text-green-600' ?>"></div>

    Do not pay to much attention to this comment, it's just for the science.

    • Like 1
  13. On 8/8/2023 at 1:59 AM, protro said:

    if it is shipped as a PW Module

    It is. You will be able to use vite module with static or dynamic routes. Two-month bug hunt completed at work so hopefully releasing a beta this weekend, I think I will find the time to finish the skyscrapers profiles based on Svelte, Vue and a dashboard sample with the launch of the module to get you up and running quickly.

    I can't wait to hear what you think of something that, thanks to @ryan since pw-3.0.173, makes things so much easier about routing for a simple SPA with less than ten lines of code.

    About the Inertia setup, I hope to make sir @FireWire switch from laravel or at least to give a try 🙂. Stay tuned.


    • Like 2
  14. 2 hours ago, kunago said:

    No idea what's going on but I will set an extra log for monitoring that specific site.

    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.

    • Like 2
  15. Its just a matter of organizing my directory tree structure.

    when I was using MAMP, WAMP and even now in Caddytron, I was used to put in every root site folder a wwwroot folder that was the root folder of the virtualhost, so I can keep related meta files, log files, backups, or whatever, on the same directory, without having it accessible from internet. It's basically the same setup as your.

    To illustrate:

    - htdocs  
         - wwwroot 
              - index.php
              - wire 


    - /var/www/html
       - website1
            - readme.md
            - wwwroot
       - website1
            - readme.md
            - wwwroot


    About the node_modules folder, just keep in mind that is a dev folder not uploaded on production. So it doesn’t matter where you put the folder as no scripts are linked or interfering with your pw files.

    If you are working for example on a react app, svelte or vue or even a simple js/ta app, your app will be « talking » with your pw setup from Ajax call or static routes.

    You only want the final built scripts to be shipped on your production (i mean your pw setup). They will be included the same way like any other script files you are used to do.



  16. Hi @protro

    I didn't read the thread linked, but I will try to give a small insight of how I am used to dev with ProcessWire, and a note of ES6+ modules, with the answer of the import statements error, I will give you a starter module too at the end of this thread. And sorry, I have to be quick, so I am posting screenshot instead of a good formatted post, see the setup image at the end.

    First, there is nothing wrong about using a package manager like node/npm, but you should do it in order to make you the life easier. It's more true when working with all the crypto mess. A word on your previous message, almost all lib/packages are developed using JS (TypeScript) so it will work with quite every frameworks/libs (React, Svelte, Vue, whatever). Some implementation are specialized for React, not surprising, React is in JS world what Wordpress is in the PHP world (check the stats in the linked thread below, fellow members here seem to not used it, hooray, react syntax is weird and slow).

    My setup of almost every app (stay tuned as the whole things are coming published for free):

    About the ES6+ module, when working with them, you need to use JS and for production building the app, OR you can call them in your `<script></script>` by setting up the script as module by writing `<script type="module"></script>`. Keep in mind that writing calls like that in templates, make global objects, like window, not available until the document is ready making things like binding events to DOM a bit tiresome..

    And a draft of a module. It should not work as is, but it's just to give you an "image" more than words and could be written in templates. Writing JS like that (module or template) is not the better way to do it, and should be avoided, it makes things complicated when they're actually quite simple, even more when speaking about Metamask. Check the method `writeWeb3ModalScript()`, you can see that libs can be used from a CDN when published (unpkg make automatically available dist files of any packages):

    <?php namespace ProcessWire;
    class Web3 extends WireData implements Module, ConfigurableModule
      const WEB3MODAL_PROJECT_ID = ''; // read from db or .env file
      const ALCHEMY_API_KEY = ''; // read from db or .env file
      public static function getModuleInfo()
        return [
          'title' => 'Web3',
          'version' => '0.0.1',
          'summary' => 'Web3 for ProcessWire',
          'autoload' => false,
          'icon' => '',
          'requires' => [],
          'installs' => [],
      public function writeWeb3ModalScript($buttonDomID) {
        $scriptTag  = <<<EOT
        <link rel="stylesheet" href="https://unpkg.com/@rainbow-me/rainbowkit@1.0.7/dist/index.css" />
        <script type="module">
          import Onboard from 'https://unpkg.com/@web3-onboard/core'
          import injected from 'https://unpkg.com/@web3-onboard/injected-wallets'
          window.onload = async function() {
            const MAINNET_RPC_URL = 'https://mainnet.infura.io/v3/[APIKEY-HERE]'
            const onboard = Onboard({
              wallets: [injected],
              chains: [
                  id: '0x1',
                  token: 'ETH',
                  label: 'Ethereum Mainnet',
                  rpcUrl: MAINNET_RPC_URL
            const wallets = await onboard.connectWallet()
            const connectButton = document.getElementById("$buttonDomID");
            // 3. Sign In
            window.onSignIn = function() {
              console.log(window, window.onSignIn);
        return $scriptTag;
      // wallet can be an ENS formatted address
      public function getTokensForWallet($wallet)
        $url = "https://eth-mainnet.g.alchemy.com/nft/v3/" . self::ALCHEMY_API_KEY;
        $url .= "/getNFTsForOwner?owner=" . $wallet;
        // send get request to alchemy api 
        $http = new WireHttp();
        $response = $http->getJSON($url);
        return $response;
      // two fields in the backend
    	 * Config inputfields
    	 * @param InputfieldWrapper $inputfields
    	public function getModuleConfigInputfields($inputfields) {
    		$modules = $this->wire()->modules;
    		/** @var InputfieldFieldset $fs */
    		$fs = $modules->get('InputfieldFieldset');
    		$fs->label = $this->_('API Configuration');
    		/** @var InputfieldCheckbox $f */
    		$f = $modules->InputfieldText;
    		$f_name = 'web3modal_project_id';
    		$f->name = $f_name;
    		$f->label = $this->_('Web3Modal Project ID');
    		$f->description = $this->_('Get Key there: https://cloud.walletconnect.com');
    		$f->columnWidth = 50;
        $f->value = $this->web3modal_project_id;
    		/** @var InputfieldText $f */
    		$f = $modules->InputfieldText;
    		$f_name = 'alchemy_api_key';
    		$f->name = $f_name;
    		$f->label = $this->_('Alchemy API Key');
        $f->description = $this->_('Get Key there: https://dashboard.alchemy.com');
    		$f->columnWidth = 50;
        $f->value = $this->alchemy_api_key;



    (The NPM package is still not available publicly, but not fully required)

    I will come back later with a working example using a CDN and a small example of a built js app working with PW. In the meantime, I'll leave you to ponder.


    • Like 1
    • Thanks 1
  17. Hi,

    This message is to be taken as informational and being transparency, NOT as a security alert.


    In short: The module code do not contain vulnerabilities, you are safe to use it.

    In depth:

    Years ago, I could spot some offsec users cloning/forking the project on Github. Theses last days, the project got more activities that can be seen on this graph and it look like the module is now included in some open-source offensive security tools.

    I took a few hours to find and go back to these tools and took the liberty of testing them myself on three online sites, based on Processwire with the module installed. I obtained no negative results, no red flags to deplore. What's more, the code is now monitored to automatically find and correct vulnerabilities in open source code and dependencies with security tools and DeepCode AI. 

    If you ever find something or even if you are not sure about it, feel free to contact me by following the Security Policy.

    Have a nice day.

    • Like 5
  18. Hi @theoretic 

    Without details about how "big" the database is, I do not see any risks to upgrade to InnoDB. You should read the introduction made by @teppo and the post written by @ryan 



    A nice and short explanation by @clsource :  https://github.com/joyofpw/how-to-install-processwire#which-engine-is-better-myisam-or-innodb

    And of course, ingesting the official mysql dev doc (choose the right version according to your setup):


    You might need to adjust some buffer settings, to get a first insight of it, you could run mysql-tuner, it take seconds to install and run, in order to get an easy to read report (steps below).

    ### Install wget (mandatory)
    apt-get update
    apt-get install -y wget
    ### Download mysqltuner
    wget http://mysqltuner.pl/ -O mysqltuner.pl
    wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/basic_passwords.txt -O basic_passwords.txt
    wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/vulnerabilities.csv -O vulnerabilities.csv
    ### Run MySQLTuner
    chmod u+x mysqltuner.pl
    ./mysqltuner.pl --user $MYSQL_USER --pass $MYSQL_PASSWORD


    • Like 4
  19. I also use AppApi frequently, you can pull it from AppApi if the code is server side, or, with js dotenv():

    // .env file
    // your module/template code
        const MyApiCall = async (url) => {
            let connect = await fetch(url, {
                method: 'GET',
                credentials: 'same-origin',
                mode: 'same-origin',
                headers: {
                    'x-api-key': process.env.SECRET_API_TOKEN,
            let result = await connect.json()
            return result

    But it seem you are writing js code from php templates instead of using js components and/or a built app, then:

    // load .env
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ /* where is .env file */);
        const MyApiCall = async (url) => {
            let connect = await fetch(url, {
                method: 'GET',
                credentials: 'same-origin',
                mode: 'same-origin',
                headers: {
                    'x-api-key': <?php $_ENV['SECRET_API_TOKEN'] ?>,
            let result = await connect.json()
            return result


    3 hours ago, psy said:

    am sure others must have similar issues connecting PW via JS

    dotenv. You just do not want to leak it, whatever the method used. Maybe just try to find an article that correspond you better to understand the process.

    • Like 2
  20. What Steve said.

    And if you need it from your js components, there is dotenv. Take care to not leak the token, if you build the app with Vite, only variable with VITE prefix are exposed as import.meta.env.*

    VITE_BAAAAAAD=abcd1234 (leaked)

    DEADBEEF=abcd1234 (not leaked / undefined)


    • Like 3
    • Thanks 1
  • Create New...