We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 43374
    • 39 Posts
    I would like to remove the "404 HTTP Response code" from the "error_page" system setting event. Where is it located in the /core/?

    Why?:

    I created a page based on a large relational database with to many pages to be handled by modx. So I created a uri column for each page and wrote a snippet that catches the URI from the URL, catches the other data from the table and placed this snipped on the page that is called from the "error_page" system setting event. This is all working very awesome.

    But I added all pages to the google webmaster tool sitemap section and I see from the warnings that a "404 HTTP Response code" must be send during this process. So I want to modify the code in the core so that the "404 HTTP Response code" is not send to google on the "error_page" call.

    Edit: MODX Revolution 2.2.7-pl (traditional)

    This question has been answered by BobRay. See the first response.

    [ed. note: sh0ck23 last edited this post 13 years, 2 months ago.]
      • 43374
      • 39 Posts
      I think I found the coresponding passage in /core/model/modx/modx.class.php

           * Forwards the request to another resource without changing the URL.
           *
           * @param integer $id The resource identifier.
           * @param string $options An array of options for the process.
           */
          public function sendForward($id, $options = null) {
              if (!$this->getRequest()) {
                  $this->log(modX::LOG_LEVEL_FATAL, "Could not load request class.");
              }
              $idInt = intval($id);
              if (is_string($options) && !empty($options)) {
                  $options = array('response_code' => $options);
              } elseif (!is_array($options)) {
                  $options = array();
              }
              $this->elementCache = array();
              if ($idInt > 0) {
                  $merge = array_key_exists('merge', $options) && !empty($options['merge']);
                  $currentResource = array();
                  if ($merge) {
                      $excludes = array_merge(
                          explode(',', $this->getOption('forward_merge_excludes', $options, 'type,published,class_key,context_key')),
                          array(
                              'content'
                              ,'pub_date'
                              ,'unpub_date'
                              ,'richtext'
                              ,'_content'
                              ,'_processed'
                          )
                      );
                      reset($this->resource->_fields);
                      while (list($fkey, $fval) = each($this->resource->_fields)) {
                          if (!in_array($fkey, $excludes)) {
                              if (is_scalar($fval) && $fval !== '') {
                                  $currentResource[$fkey] = $fval;
                              } elseif (is_array($fval) && count($fval) === 5 && $fval[1] !== '') {
                                  $currentResource[$fkey] = $fval;
                              }
                          }
                      }
                  }
                  $this->resource= $this->request->getResource('id', $idInt, array('forward' => true));
                  if ($this->resource) {
                      if ($merge && !empty($currentResource)) {
                          $this->resource->_fields = array_merge($this->resource->_fields, $currentResource);
                          $this->elementCache = array();
                          unset($currentResource);
                      }
                      $this->resourceIdentifier= $this->resource->get('id');
                      $this->resourceMethod= 'id';
                      if (isset($options['response_code']) && !empty($options['response_code'])) {
                          header($options['response_code']);
                      }
                      $this->request->prepareResponse();
                      exit();
                  }
                  $options= array_merge(
                      array(
                          'error_type' => '404'
                          ,'error_header' => $this->getOption('error_page_header', $options,'HTTP/1.1 404 Not Found')
                          ,'error_pagetitle' => $this->getOption('error_page_pagetitle', $options,'Error 404: Page not found')
                          ,'error_message' => $this->getOption('error_page_message', $options,'<h1>Page not found</h1><p>The page you requested was not found.</p>')
                      ),
                      $options
                  );
              }
              $this->sendError($id, $options);
          }
      
          /**
           * Send the user to a MODX virtual error page.
           *
           * @uses invokeEvent() The OnPageNotFound event is invoked before the error page is forwarded
           * to.
           * @param array $options An array of options to provide for the OnPageNotFound event and error
           * page.
           */
          public function sendErrorPage($options = null) {
              if (!is_array($options)) $options = array();
              $options= array_merge(
                  array(
                      'response_code' => $this->getOption('error_page_header', $options, 'HTTP/1.1 404 Not Found')
                      ,'error_type' => '404'
                      ,'error_header' => $this->getOption('error_page_header', $options, 'HTTP/1.1 404 Not Found')
                      ,'error_pagetitle' => $this->getOption('error_page_pagetitle', $options, 'Error 404: Page not found')
                      ,'error_message' => $this->getOption('error_page_message', $options, '<h1>Page not found</h1><p>The page you requested was not found.</p>')
                  ),
                  $options
              );
              $this->invokeEvent('OnPageNotFound', $options);
              $this->sendForward($this->getOption('error_page', $options, '404'), $options);
          }
      


      I am not quite sure which part needs to be removed to not send the error response to google. Any ideas?

      Or am I wrong and I need to make the modifications in the OnPageNotFound event? If yes where do I find this? [ed. note: sh0ck23 last edited this post 13 years, 2 months ago.]
      • discuss.answer
        • 3749
        • 24,544 Posts
        I think you might want to put your code in a plugin attached to the OnPageNotFound event rather than in a snippet. In your code, you can determine if it's one of your "special" pages from the URL. If it is, forward the user with $modx->sendRedirect($url) or $modx->sendForward($url). If not, just return an empty string and let MODX process the 404 normally.

        That should avoid the 404, and you won't have to hack the MODX core or worry about your changes being overwritten when you upgrade MODX. [ed. note: BobRay last edited this post 13 years, 2 months ago.]
          Did I help you? Buy me a beer
          Get my Book: MODX:The Official Guide
          MODX info for everyone: http://bobsguides.com/modx.html
          My MODX Extras
          Bob's Guides is now hosted at A2 MODX Hosting
          • 43374
          • 39 Posts
          Thanks I will have a look to your described OnHandleRequest method if I get a bit more spare time, since it would also give the benfit that I can display "real" error-pages for non existing pages.

          For now I went the dirty quick way so that google can continue to index the pages. I did it with with the following hack:

           /**
               * Forwards the request to another resource without changing the URL.
               *
               * @param integer $id The resource identifier.
               * @param string $options An array of options for the process.
               */
              public function sendForward($id, $options = null) {
                  if (!$this->getRequest()) {
                      $this->log(modX::LOG_LEVEL_FATAL, "Could not load request class.");
                  }
                  $idInt = intval($id);
                  if (is_string($options) && !empty($options)) {
                      $options = array('response_code' => $options);
                  } elseif (!is_array($options)) {
                      $options = array();
                  }
                  $this->elementCache = array();
                  if ($idInt > 0) {
                      $merge = array_key_exists('merge', $options) && !empty($options['merge']);
                      $currentResource = array();
                      if ($merge) {
                          $excludes = array_merge(
                              explode(',', $this->getOption('forward_merge_excludes', $options, 'type,published,class_key,context_key')),
                              array(
                                  'content'
                                  ,'pub_date'
                                  ,'unpub_date'
                                  ,'richtext'
                                  ,'_content'
                                  ,'_processed'
                              )
                          );
                          reset($this->resource->_fields);
                          while (list($fkey, $fval) = each($this->resource->_fields)) {
                              if (!in_array($fkey, $excludes)) {
                                  if (is_scalar($fval) && $fval !== '') {
                                      $currentResource[$fkey] = $fval;
                                  } elseif (is_array($fval) && count($fval) === 5 && $fval[1] !== '') {
                                      $currentResource[$fkey] = $fval;
                                  }
                              }
                          }
                      }
                      $this->resource= $this->request->getResource('id', $idInt, array('forward' => true));
                      if ($this->resource) {
                          if ($merge && !empty($currentResource)) {
                              $this->resource->_fields = array_merge($this->resource->_fields, $currentResource);
                              $this->elementCache = array();
                              unset($currentResource);
                          }
                          $this->resourceIdentifier= $this->resource->get('id');
                          $this->resourceMethod= 'id';
                          if (isset($options['response_code']) && !empty($options['response_code'])) {
                              header($options['response_code']);
                          }
                          $this->request->prepareResponse();
                          exit();
                      }
                      $options= array_merge(
                          array(
                              'error_type' => '404'
                              ,'error_header' => $this->getOption('error_page_header', $options,'')
                              ,'error_pagetitle' => $this->getOption('error_page_pagetitle', $options,'Error 404: Page not found')
                              ,'error_message' => $this->getOption('error_page_message', $options,'<h1>Page not found</h1><p>The page you requested was not found.</p>')
                          ),
                          $options
                      );
                  }
                  $this->sendError($id, $options);
              }
          
              /**
               * Send the user to a MODX virtual error page.
               *
               * @uses invokeEvent() The OnPageNotFound event is invoked before the error page is forwarded
               * to.
               * @param array $options An array of options to provide for the OnPageNotFound event and error
               * page.
               */
              public function sendErrorPage($options = null) {
                  if (!is_array($options)) $options = array();
                  $options= array_merge(
                      array(
                          'response_code' => $this->getOption('error_page_header', $options, '')
                          ,'error_type' => '404'
                          ,'error_header' => $this->getOption('error_page_header', $options, '')
                          ,'error_pagetitle' => $this->getOption('error_page_pagetitle', $options, 'Error 404: Page not found')
                          ,'error_message' => $this->getOption('error_page_message', $options, '<h1>Page not found</h1><p>The page you requested was not found.</p>')
                      ),
                      $options
                  );
                  $this->invokeEvent('OnPageNotFound', $options);
                  $this->sendForward($this->getOption('error_page', $options, '404'), $options);
              }
          


          At least for google this is working for now
            • 22303 MODX Staff
            • 10,725 Posts
            You should be doing this in a plugin OnPageNotFound. This has been described many times...

            https://forums.modx.com/thread/35476/can-snippets-plugins-make-use-of-intercept-friendly-urls#dis-post-194484