Jump to content

psy

Members
  • Posts

    738
  • Joined

  • Last visited

  • Days Won

    11

Posts posted by psy

  1. There are many forum topics and suggested solutions to problems uploading images in PW admin. I've read all I can find but none address the problem I'm experiencing. It's consistent and repeatable.

    I have an image field in my template (duh!) and I can successfully upload any images with an approved image file type that has a file size over 10kb. Any images (png or jpg in this case) with file size of <10kb fail with the following error:

    image.jpeg.5ff3bc523b030a8c00acc60c28a104b7.jpeg

    I have even taken one of the small images, given it a bigger canvas in Photoshop, converted to PNG/JPG and successfully uploaded it. I could also hack it and make all my images bigger then use the api/image variations to reduce them on frontend output but that's not the point and a lot of unnecessary effort and wasted disk storage.

    Suggestions on how to fix the underlying problem most welcome.

    TIA

    Solved

    Thanks @netcarver for suggesting it may be a ModSecurity issue. Nailed it. Web host whitelisted my IP from their (obscure) rule and the uploads worked perfectly ? 

  2.  Nothing in this post since 2020 then a client got this today...

    Similar to above comments, I'm convinced it's just a nasty extortion threat and should be ignored. Form is in Formbuilder iframe and full of all ProcessWire & FB sanity checks. Site is functional and no obvious hacks. Told client that if it was real, they should feel privileged to be the first ever recognised PW hack victim. Also feeling a bit chuffed that this little, local Aussie site was found on the global hacker network.

     

    Forms-•-ProcessWire-•-xxx-com.png

  3. @netcarver

    Thanks for your input.

    1. Site doesn't use any hooks
    2. Searched Google, forum but not repo. Will do so now. There was an old post that was vaguely similar but didn't have an answer. See link below
    3. Turning off the error may hide the error message but, you're right, it will totally obscute the real issue.

     

  4. I've been working on a a new site for weeks. $session did it's normal, wonderful stuff until today when it didn't - boom!!!

    $session now occasionally holds vars from one page to another. The killer is $session->location or $session->redirect. Before redirecting, the page crashes with:
    image.thumb.png.c979bc1015e2cfec5d2826920284b076.png

    I went back to basics with the default theme:

    Spoiler

    <?php namespace ProcessWire;

    // home.php (homepage) template file. 

    $session->set('hello', "hello from page 1");

    // Primary content is the page body copy
    $content = $page->body;

    // Append navigation to child pages underneath the body copy
    // See the _func.php file for the renderNav() function example
    $content .= renderNav($page->children); 

    // if there are images, lets choose one to output in the sidebar
    if(count($page->images)) {
        
        // if the page has images on it, grab one of them randomly... 
        $image = $page->images->getRandom();
        
        // resize it to 400 pixels wide
        $image = $image->width(400); 
        
        // output the image at the top of the sidebar
        $sidebar = "<img src='$image->url' alt='$image->description' />";
        
        // if image has a description, display it underneath
        if($image->description) $sidebar .= "<blockquote>$image->description</blockquote>";
        
        // append sidebar text content if page has it
        $sidebar .= $page->sidebar; 
        
    } else {
        // no images... 
        // make sidebar contain text content if page has it
        $sidebar = $page->sidebar; 
    }

    // basic-page template:

    <?php namespace ProcessWire;

    // basic-page.php template file 

    print_r($_SESSION);
    print_r($session->getAll());
    print_r($session->hello);
    $session->location($pages->get(1)->url);

    // Primary content is the page's body copy
    $content = $page->body; 

    // If the page has children, then render navigation to them under the body.
    // See the _func.php for the renderNav example function.
    if($page->hasChildren) {
        $content .= renderNav($page->children);
    }

    // if the rootParent (section) page has more than 1 child, then render 
    // section navigation in the sidebar (see _func.php for renderNavTree).
    if($page->rootParent->hasChildren > 1) {
        $sidebar = renderNavTree($page->rootParent, 3); 
        // make any sidebar text appear after navigation
        $sidebar .= $page->sidebar; 
    }

    // in default install basic-page template
    // on frontend, clicking menu link from home page to about page

    // print_r($_SESSION);
    Array ( [Session] => Array ( [hello] => hello from page 1 ) )

    // print_r($session->getAll());
    Array ( [hello] => hello from page 1 ) 
     

    // print_r($session->hello); 
    hello from page 1

    // $session->location($pages->get(1)->url);
    Fatal error: Exception: Method WireHttp::sendStatusHeader does not exist or is not callable in this context (in /home/path/to/my/site.com/wire/core/Wire.php line 563) #0 /home/path/to/my/site.com/wire/core/Wire.php(419): ProcessWire\Wire->___callUnknown('sendStatusHeade...', Array) #1 /home/path/to/my/site.com/wire/core/WireHooks.php(952): ProcessWire\Wire->_callMethod('___callUnknown', Array) #2 /home/path/to/my/site.com/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\WireHttp), 'callUnknown', Array) #3 /home/path/to/my/site.com/wire/core/Wire.php(487): ProcessWire\Wire->__call('callUnknown', Array) #4 /home/path/to/my/site.com/wire/core/Session.php(1401): ProcessWire\Wire->__call('sendStatusHeade...', Array) #5 /home/path/to/my/site.com/wire/core/Wire.php(419): ProcessWire\Session->___redirect('/', 302) #6 /home/path/to/my/site.cli in /home/path/to/my/site.com/index.php on line 64
    Fatal error: Uncaught ProcessWire\WireException: Method WireHttp::sendStatusHeader does not exist or is not callable in this context in /home/path/to/my/site.com/wire/core/Wire.php:563 Stack trace: #0 /home/path/to/my/site.com/wire/core/Wire.php(419): ProcessWire\Wire->___callUnknown('sendStatusHeade...', Array) #1 /home/path/to/my/site.com/wire/core/WireHooks.php(952): ProcessWire\Wire->_callMethod('___callUnknown', Array) #2 /home/path/to/my/site.com/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\WireHttp), 'callUnknown', Array) #3 /home/path/to/my/site.com/wire/core/Wire.php(487): ProcessWire\Wire->__call('callUnknown', Array) #4 /home/path/to/my/site.com/wire/core/WireShutdown.php(405): ProcessWire\Wire->__call('sendStatusHeade...', Array) #5 /home/path/to/my/site.com/wire/core/WireShutdown.php(581): ProcessWire\WireShutdown->sendFatalHea in /home/path/to/my/site.com/wire/core/Wire.php on line 563

    Using ProcessWire 3.0.212 dev

    PHP v8.1 (tried 7.4 & 8.0 too)

    Error occurs in Chrome & Firefox

    Editing modules, eg turning TracyDebugger on/off also triggers the problem

    Error occurs in front and back end. Often, clicking on a link to a different page clears the error but $session still screwy.

    Have no idea why PW suddenly stopped correctly wiring $session.

    Is this a bug? Am I doing something wrong?

    Help & ideas on how to fix gratefully accepted.

     

    Solved:

    Upload a fresh copy of WireHTTP to my server. Previous version may have been corrupted in transit.

  5. Thanks for the tips netcarver. Will compare the headers ? 

    I had "Content-Type" then looked into WireHTTP.php where it's listed everywhere in lowercase, eg:

    <?php
    
    public function post($url, $data = array(), array $options = array()) {
    		if(!isset($this->headers['content-type'])) $this->setHeader('content-type', 'application/x-www-form-urlencoded; charset=utf-8');
    		return $this->send($url, $data, 'POST', $options);
    	}

     

  6. I'm trying to post json data to an endpoint with:

    <?php
    
            $http = new WireHttp();
            $http->setHeaders([
                'X-Auth-Token' => 'XXXXXX',
                'Accept'=> 'application/json',
                'content-type' => 'application/json'
            ]);
            $myEndPoint = "https://myendpoint.com/api";
            $params = [
                'parent_id' => 0,
                'name' => "My Name",
                'is_visible' => false
            ];
            $paramsJSON = json_encode($params);
            $http->setData($paramsJSON);
    
            $response = $http->post($myEndPoint);
            if($http->getError()) {
                echo "HTTP request failed: " . $http->getError();
                $this->die;
            }
    
            //.....
        }

    It fails every time no matter how I present the $params with: HTTP request failed: 400 Bad Request:.

    It works successfully when I post through Postman app.

    The endpoint & headers are correct and used successfully elsewhere with $http->get

    Help to fix much appreciated.

  7. An alternative approach using native PW is to make your titles the shorter version and use a field, eg 'headline' for the lengthy version. In your templates use:

    <h1><?=$page->get('headline|title')?></h1>

    This will output the headline if it's available and if not, the title. You can then also use the shorter version in front end menus, etc.

    In the admin page list, it will default to the shorter 'title' field.

    If you need the front end page URL to be the longer version for SEO, you could add a hook in templates/ready.php, eg (untested):

    <?php
    
    $wire->addHookBefore('Pages::saved', function(HookEvent $event) {
      $page = $event->arguments(0);
      
      // ensure it meets the requirements
      if (empty($page->headline) || $page->template !== 'your-template-name') return;
      
      // regenerate the page url from the headline field
      $page->url = wire('sanitizer')->pageName('headline');
    
      // Populate back arguments 
      $event->arguments(0, $page);
    });

    And another way....

    In your template, Advanced tab, under "List of fields to display in the Admin Page List", simply enter {name-of-your-shorter-field}

  8. On 3/7/2022 at 9:30 PM, Sebi said:

    Yep, that's right. The module has basically the same code as the PageApiAccess class that I posted in the other thread. I added an improvement for handling the "lang"-GET-param, that enables you to switch to another language in a multilang environment. But everything else is the same code.

    Hi @Sebi Would you please give some actual code examples? I've tried all sorts of variations and if I manage to get a response, it's always in the default lang (English), eg:

    Spoiler
    <script>
    // Javscript in page template
      
          const testing = async (url) => {
              let connect = await fetch(url, {
                  method: 'GET',
                  credentials: 'same-origin',
                  mode: 'same-origin',
                  headers: {
                      'x-api-key': 'xxxxxxxxxxxxxxxxxxxxxxx',
                  }
              })
    
              let result = await connect.json()
              return result
          }
    
    // Testing AppApi only
          
    // const url ="/api/v1/licki/test"        // works. Multilang not tested
    // const url ="/api/v1/users/41"          // works. Multilang not tested
          
    // Testing AppApiPage
          
    // const url = "/api/page/1/?lang=german"  // returns default lang obj {id: 1, name: 'home', title: 'Home', path: '/'}.
                                               // title should be German 'Startseite' and path '/de/'
          
    // const url = "/api/page/1/de"            // fails with {error: 'Method Page::localUrl does not exist or is not callable 
                                               // in this context', devmessage: {…}}
          
    // const url = "/api/page/de/1"            // fails with {error: 'Method Page::localUrl does not exist or is not callable 
                                               // in this context', devmessage: {…}}
          
    // const url = "/api/page/home/de"         // fails with {error: 'Method Page::localUrl does not exist or is not callable 
                                               // in this context', devmessage: {…}}
          
    // const url = "/api/page/1/?lang=de"      // fails with {error: 'Method Page::localUrl does not exist or is not callable 
                                               // in this context', devmessage: {…}} 
    
         const url = "/api/page/1/?lang=german"
    		testing(url).then((res) => {
            console.log(res)
            }
         )
    </script>

     

    Thanks for all the work you've done with AppApi and the add-on modules.

    Hope you can help.

    Cheers
    psy

    SOLVED (almost!)

    In _init.php:

    Spoiler

     

    <?php
    
    // Check if AppApi is available:
    if (wire('modules')->isInstalled('AppApi')) {
        $module = $this->wire('modules')->get('AppApi');
        // Check if page was called via AppApi
        if($module->isApiCall()){
            $slug = $user->language->name !== 'default' ? '/' . $pages->get(1)->getLanguageValue($user->language, 'name') : '';
              $output = [
                'id' => $page->id,
                'name' => $page->name,
                'title' => $page->title,
                'slug' => \ltrim($slug, '/'),
                'path' => $slug . $page->path,
                'lang' => $user->language->name,
            ];
            // sendResponse will automatically convert $output to a JSON-string:
           AppApi::sendResponse(200, $output);
        }
    }

     

    In my page template javascript:

    Spoiler
    <script>
    	const pathArray = window.location.pathname.split('/')
    	console.log(pathArray)
    
        const url = `/api/page/1028/?lang=${pathArray[1]}`
        testing(url).then((res) => {
            console.log(res)
            }
         )
    </script>

     

    In my AppApi custom class to make it multi-language:

    Spoiler
    <?php
        public static function myFunction($data)
        {
            $pages = wire('pages');
            $input = wire('input');
            $sanitizer = wire('sanitizer');
            $languages = wire('languages');
            $modules = wire('modules');
    
            $data = AppApiHelper::checkAndSanitizeRequiredParameters($data, ['id|int']);
    
            if (!empty($input->get->lang)) {
                $slug = $sanitizer->pageName($input->get->lang);
                if ($modules->isInstalled('AppApiPage')) {
                    $langName = AppApiPage::getLanguageCode($slug);
                    if ($langName)  $languages->setLanguage($langName);
                }
            }
            $response = new \StdClass();
            $page = $pages->get($data->id);
    
            if (!$page->id || $page instanceof NullPage) {
                throw new \Exception('Not found', 404);
            }
    
            $response->id = $page->id;
            $response->name = $page->name;
            $response->title = $page->title;
    
            return $response;
    
        }

     

    Everything seems to work fine EXCEPT when using AppApiPage on the home page. The response is still always in the default language.

     

  9. It worked before and now not ?

    The web server was recently upgraded to PHP8 and I know PHP8 is much stricter on argument typing than previous PHP versions, and this blip resulted in a Server 500 error:

    2022-11-16 14:56:21	guest	https://xxxxxxx.com/api/	Fatal Error:  Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, string given in /home/xxxxxxx/public_html/wire/core/PagesLoader.php:845

    The code was a 'page get' selector request in an ajax call. It all worked before the PHP update and I'm sure there are others using $pages->get() without issues on PHP8.

    $pages->get("id=". $sanitizer->int($data->pid))

    I also tried it without the "id=".  I think the problem is more that $options is a string in the line in the PagesLoader.php:

    <?php
    $options = count($options) ? array_merge($defaults, $options) : $defaults;

    Any ideas on how to fix?

    Thanks, psy

    Solution

    Changed line 845 in PagesLoader.php to confirm $options is an array and the site worked again.

    		$options = is_array($options) && count($options) ? array_merge($defaults, $options) : $defaults;

     

  10. On many of my sites I have a page for business information which includes:

    • toggle for site down for maintenance or live
    • combo field for business name, address, phone, email, contact name, etc
    • functional field for common phrases

    The combo field is great in this scenario. The data is fairly static and I only need to add the one combo field for a bunch of 'sub' information, bits of which may be used throughout the site. The alternative is to create a fieldset with individual fields, all of which would only be used in a single template and have one entry per field.

    • Like 2
  11. Hi @Jan Romero The PW docs refer to language codes. I didn't realise language codes and country codes were slightly different. Solution discovered by trial and error, and ironically, Google's Search help. Initially the warning only appeared when that lang page loaded, but once done so, the whole site had "Dangerous" in the browser address bar. Refreshing using the default lang cleared the message.

     

  12. This is my first multi-lang site and client, bless his cotton socks, has chosen to have the site in at least 10 languages.

    Have figured out many things but Chrome is not playing nice. The default lang is English UK (lang url code is 'default' or 'gb'). On some langs, esp English US (lang url code is 'en-us') and Japanese (lang url code 'jp'), it's flagging the pages as "dangerous - could be phishing". All works fine in Firefox.

    Questions:

    1. How to stop Google flagging valid lang pages as dangerous?
    ANSWER: Use the language code NOT the country code in the URL, eg English US = en-us (not just 'us') and Japanese = ja (not 'jp').

    2. On langs that don't follow the 'English' convention of text LTR, how do I set alternatives in the HMTL? eg Japanese is 'top to bottom, right to left'. Have done what I can in the CSS using logical properties (eg margin-block-start, padding-inline-end, etc)
    ANSWER: Add the language name as a class in the body tag then set the writing mode in CSS, eg:

    /* japanese */
    body.japanese {
      writing-mode: vertical-rl;
      min-height: auto;
      overflow-x: auto;
    }

    HTH

    psy

    • Like 1
×
×
  • Create New...