Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8653147
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T14:28:23+00:00 2026-06-12T14:28:23+00:00

A default error logging using vqmod is as follows: ———- Date: 2012-10-09 19:46:06 ~

  • 0

A default error logging using vqmod is as follows:

---------- Date: 2012-10-09 19:46:06 ~ IP : 127.0.0.1 ----------
REQUEST URI : /oc/
MOD DETAILS:
   modFile   : C:\wamp\www\oc\vqmod\xml\templace.xml
   id        : Template
   version   : 1.5.2 - 1.5.2.1
   vqmver    : 1.0.8
   author    : templace.com
SEARCH NOT FOUND (ABORTING MOD): require_once(foo . 'library/template.php');

----------------------------------------------------------------------

Example vqmod causing the error

<modification>
    <id>Templace</id>
    <version>1.5.2 - 1.5.2.1</version>
    <author>templace.com</author>   
    <vqmver>1.0.8</vqmver>

    <file name="system/startup.php">
        <operation>
            <search position="before"><![CDATA[
            require_once(foo . 'library/template.php');
            ]]></search>
            <add><![CDATA[
            require_once(DIR_SYSTEM . 'library/templace.php');
            ]]></add>
        </operation>
    </file>
</modification>

To resole this issue I would have to open the vqmod file templace.xml and search for the file[name] this error is referring too.

QUESTION: How could I add the parent file[name] the actual error is referring too?

E.g adding: “system/startup.php” to the error message to make it easier to debug.

vqmod.php

/**
 * VQMod
 * @description Main Object used
 */
final class VQMod {
    private $_vqversion = '2.1.7';
    private $_modFileList = array();
    private $_mods = array();
    private $_filesModded = array();
    private $_cwd = '';
    private $_doNotMod = array();
    private $_virtualMode = true;

    public $useCache = false;
    public $logFilePath = 'vqmod/vqmod.log';
    public $vqCachePath = 'vqmod/vqcache/';
    public $protectedFilelist = 'vqmod/vqprotect.txt';
    public $logging = true;
    public $cacheTime = 5; // local=5secs live=60secs
    public $log;

    /**
     * VQMod::__construct()
     *
     * @param bool $path File path to use
     * @param bool $logging Enable/disabled logging
     * @return null
     * @description Startup of VQMod
     */
    public function __construct($path = false, $logging = true) {
        if(!class_exists('DOMDocument')) {
            die('ERROR - YOU NEED DOMDocument INSTALLED TO USE VQMod');
        }

        if(!$path){
            $path = dirname(dirname(__FILE__));
        }
        $this->_setCwd($path);

        $this->logging = (bool) $logging;
        $this->log = new VQModLog($this);

        $this->_getMods();
        $this->_loadProtected();
    }

    /**
     * VQMod::modCheck()
     *
     * @param string $sourceFile path for file
     * @return string
     * @description Checks if a file has modifications and applies them, returning cache files or the file name
     */
    public function modCheck($sourceFile) {

        if(!preg_match('%^([a-z]:)?[\\\\/]%i', $sourceFile)) {
            $sourcePath = $this->path($sourceFile);
        } else {
            $sourcePath = realpath($sourceFile);
        }

        if(!$sourcePath || is_dir($sourcePath) || in_array($sourcePath, $this->_doNotMod)) {
            return $sourceFile;
        }

        $stripped_filename = preg_replace('~^' . preg_quote($this->getCwd(), '~') . '~', '', $sourcePath);
        $cacheFile = $this->_cacheName($stripped_filename);

        if($this->useCache && file_exists($cacheFile)) {
            //return $cacheFile; // useCache being Deprecated in favor of cacheTime
        }

        if(isset($this->_filesModded[$sourcePath])) {
            return $this->_filesModded[$sourcePath]['cached'] ? $cacheFile : $sourceFile;
        }

        $changed = false;
        $fileHash = sha1_file($sourcePath);
        $fileData = file_get_contents($sourcePath);

        foreach($this->_mods as $modObject) {
            foreach($modObject->mods as $path => $mods) {
                if($this->_checkMatch($path, $sourcePath)) {
                    $modObject->applyMod($mods, $fileData);
                }
            }
        }

        // START QPHORIA CACHELOCK CODE
        //
        if (sha1($fileData) != $fileHash) {
            $writePath = $cacheFile;
            $cacheLock = false;
            if(file_exists($writePath) && ((filemtime($writePath) + (float)$this->cacheTime) >= time())) {
                $cacheLock = true;
                $changed = true;
            }
            if(!$cacheLock && (!file_exists($writePath) || is_writable($writePath))) {
                file_put_contents($writePath, $fileData);
                $changed = true;
            } else {
                //file_put_contents('./cachelock.txt', "$writePath \r\n", FILE_APPEND); // debugging only.
            }
            //file_put_contents('./cachetotal.txt', "$writePath \r\n", FILE_APPEND);
        } // END QPHORIA CACHELOCK CODE

        /* Original Code
        if(sha1($fileData) != $fileHash) {
            $writePath = $this->_virtualMode ?  $cacheFile : $sourcePath;
            if(!file_exists($writePath) || is_writable($writePath)) {
                file_put_contents($writePath, $fileData);
                $changed = true;
            }
        }*/

        $this->_filesModded[$sourcePath] = array('cached' => $changed);
        return $changed ? $writePath : $sourcePath;
    }

    /**
     * VQMod::path()
     *
     * @param string $path File path
     * @param bool $skip_real If true path is full not relative
     * @return bool, string
     * @description Returns the full true path of a file if it exists, otherwise false
     */
    public function path($path, $skip_real = false) {
        $tmp = $this->_cwd . $path;
        $realpath = $skip_real ? $tmp : realpath($tmp);
        if(!$realpath) {
            return false;
        }
        if(is_dir($realpath)) {
            $realpath = rtrim($realpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        }
        return $realpath;
    }

    /**
     * VQMod::getCwd()
     *
     * @return string
     * @description Returns current working directory
     */
    public function getCwd() {
        return $this->_cwd;
    }

    /**
     * VQMod::_getMods()
     *
     * @return null
     * @description Gets list of XML files in vqmod xml folder for processing
     */
    private function _getMods() {

        $this->_modFileList = glob($this->path('vqmod/xml/') . '*.xml');

        if($this->_modFileList) {
            $this->_parseMods();
        } else {
            $this->log->write('NO MODS IN USE');
        }
    }

    /**
     * VQMod::_parseMods()
     *
     * @return null
     * @description Loops through xml files and attempts to load them as VQModObject's
     */
    private function _parseMods() {

        $dom = new DOMDocument('1.0', 'UTF-8');
        foreach($this->_modFileList as $modFileKey => $modFile) {
            if(file_exists($modFile)) {
                if(@$dom->load($modFile)) {
                    $mod = $dom->getElementsByTagName('modification')->item(0);
                    $this->_mods[] = new VQModObject($mod, $modFile, $this);
                } else {
                    $this->log->write('DOM UNABLE TO LOAD: ' . $modFile);
                }
            } else {
                $this->log->write('FILE NOT FOUND: ' . $modFile);
            }
        }
    }

    /**
     * VQMod::_loadProtected()
     *
     * @return null
     * @description Loads protected list and adds them to _doNotMod array
     */
    private function _loadProtected() {
        $file = $this->path($this->protectedFilelist);
        if($file && is_file($file)) {
            $protected = file_get_contents($file);
            if(!empty($protected)) {
                $protected = preg_replace('~\r?\n~', "\n", $protected);
                $paths = explode("\n", $protected);
                foreach($paths as $path) {
                    $fullPath = $this->path($path);
                    if($fullPath && !in_array($fullPath, $this->_doNotMod)) {
                        $this->_doNotMod[] = $fullPath;
                    }
                }
            }
        }
    }

    /**
     * VQMod::_cacheName()
     *
     * @param string $file Filename to be converted to cache filename
     * @return string
     * @description Returns cache file name for a path
     */
    private function _cacheName($file) {
        return $this->path($this->vqCachePath) . 'vq2-' . preg_replace('~[/\\\\]+~', '_', $file);
    }

    /**
     * VQMod::_setCwd()
     *
     * @param string $path Path to be used as current working directory
     * @return null
     * @description Sets the current working directory variable
     */
    private function _setCwd($path) {
        $realpath = realpath($path);
        if(!$realpath) {
            die('COULDNT RESOLVE CWD REALPATH');
        }
        $this->_cwd = rtrim($realpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
    }

    /**
     * VQMod::_checkMatch()
     *
     * @param string $modFilePath Modification path from a <file> node
     * @param string $checkFilePath File path
     * @return bool
     * @description Checks a modification path against a file path
     */
    private function _checkMatch($modFilePath, $checkFilePath) {
        $modFilePath = str_replace('\\', '/', $modFilePath);
        $checkFilePath = str_replace('\\', '/', $checkFilePath);

        $modFilePath = preg_replace('/([^*]+)/e', 'preg_quote("$1", "~")', $modFilePath);
        $modFilePath = str_replace('*', '[^/]*', $modFilePath);
        $return = (bool) preg_match('~^' . $modFilePath . '$~', $checkFilePath);
        return $return;

    }
}

/**
 * VQModLog
 * @description Object to log information to a file
 */
class VQModLog {
    private $_sep;
    private $_vqmod;
    private $_defhash = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';
    private $_logs = array();

    /**
     * VQModLog::__construct()
     *
     * @param VQMod $vqmod VQMod main class as reference
     * @return null
     * @description Object instantiation method
     */
    public function __construct(VQMod $vqmod) {
        $this->_vqmod = $vqmod;
        $this->_sep = str_repeat('-', 70);
    }

    /**
     * VQModLog::__destruct()
     *
     * @return null
     * @description Logs any messages to the log file just before object is destroyed
     */
    public function __destruct() {
        if(empty($this->_logs) || $this->_vqmod->logging == false) {
            return;
        }

        $txt = array();

        $txt[] = str_repeat('-', 10) . ' Date: ' . date('Y-m-d H:i:s') . ' ~ IP : ' . (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'N/A') . ' ' . str_repeat('-', 10);
        $txt[] = 'REQUEST URI : ' . $_SERVER['REQUEST_URI'];

        foreach($this->_logs as $count => $log) {
            if($log['obj']) {
                $vars = get_object_vars($log['obj']);
                $txt[] = 'MOD DETAILS:';
                foreach($vars as $k => $v) {
                    if(is_string($v)) {
                        $txt[] = '   ' . str_pad($k, 10, ' ', STR_PAD_RIGHT) . ': ' . $v;
                    }
                }

            }

            foreach($log['log'] as $msg) {
                $txt[] = $msg;
            }

            if ($count > count($this->_logs)-1) {
                $txt[] = '';
            }
        }

        $txt[] = $this->_sep;
        $txt[] = str_repeat(PHP_EOL, 2);

        $logPath = $this->_vqmod->path($this->_vqmod->logFilePath, true);
        if(!file_exists($logPath)) {
            $res = file_put_contents($logPath, '');
            if($res === false) {
                die('COULD NOT WRITE TO LOG FILE');
            }
        }

        file_put_contents($logPath, implode(PHP_EOL, $txt), FILE_APPEND);
    }

    /**
     * VQModLog::write()
     *
     * @param string $data Text to be added to log file
     * @param VQModObject $obj Modification the error belongs to
     * @return null
     * @description Adds error to log object ready to be output
     */
    public function write($data, VQModObject $obj = NULL) {
        if($obj) {
            $hash = sha1($obj->id);
        } else {
            $hash = $this->_defhash;
        }

        if(empty($this->_logs[$hash])) {
            $this->_logs[$hash] = array(
                'obj' => $obj,
                'log' => array()
            );
        }

        $this->_logs[$hash]['log'][] = $data;

    }
}

/**
 * VQModObject
 * @description Object for the <modification> that orchestrates each applied modification
 */
class VQModObject {
    public $modFile = '';
    public $id = '';
    public $version = '';
    public $vqmver = '';
    public $author = '';
    public $mods = array();

    private $_vqmod;
    private $_skip = false;

    /**
     * VQModObject::__construct()
     *
     * @param DOMNode $node <modification> node
     * @param string $modFile File modification is from
     * @param VQMod $vqmod VQMod object as reference
     * @return null
     * @description Loads modification meta information
     */
    public function __construct(DOMNode $node, $modFile, VQmod $vqmod) {
        if($node->hasChildNodes()) {
            foreach($node->childNodes as $child) {
                $name = (string) $child->nodeName;
                if(isset($this->$name)) {
                    $this->$name = (string) $child->nodeValue;
                }
            }
        }

        $this->modFile = $modFile;
        $this->_vqmod = $vqmod;
        $this->_parseMods($node);
    }

    /**
     * VQModObject::skip()
     *
     * @return bool
     * @description Returns the skip status of a modification
     */
    public function skip() {
        return $this->_skip;
    }

    /**
     * VQModObject::applyMod()
     *
     * @param array $mods Array of search add nodes
     * @param string $data File contents to be altered
     * @return null
     * @description Applies all modifications to the text data
     */
    public function applyMod($mods, &$data) {
        if($this->_skip) return;
        $tmp = $data;

        foreach($mods as $mod) {
            $indexCount = 0;
            $tmp = $this->_explodeData($tmp);
            $lineMax = count($tmp) - 1;

            switch($mod['search']->position) {
                case 'top':
                $tmp[$mod['search']->offset] =  $mod['add']->getContent() . $tmp[$mod['search']->offset];
                break;

                case 'bottom':
                $offset = $lineMax - $mod['search']->offset;
                if($offset < 0){
                    $tmp[-1] = $mod['add']->getContent();
                } else {
                    $tmp[$offset] .= $mod['add']->getContent();
                }
                break;

                case 'all':
                $tmp = array($mod['add']->getContent());
                break;

                default:

                $changed = false;
                foreach($tmp as $lineNum => $line) {
                    if($mod['search']->regex == 'true') {
                        $pos = @preg_match($mod['search']->getContent(), $line);
                        if($pos === false) {
                            if($mod['error'] == 'log' || $mod['error'] == 'abort' ) {
                                $this->_vqmod->log->write('INVALID REGEX ERROR - ' . $mod['search']->getContent(), $this);
                            }
                            continue 2;
                        } elseif($pos == 0) {
                            $pos = false;
                        }
                    } else {
                        $pos = strpos($line, $mod['search']->getContent());
                    }

                    if($pos !== false) {
                        $indexCount++;
                        $changed = true;

                        if(!$mod['search']->indexes() || ($mod['search']->indexes() && in_array($indexCount, $mod['search']->indexes()))) {

                            switch($mod['search']->position) {
                                case 'before':
                                $offset = ($lineNum - $mod['search']->offset < 0) ? -1 : $lineNum - $mod['search']->offset;
                                $tmp[$offset] = empty($tmp[$offset]) ? $mod['add']->getContent() : $mod['add']->getContent() . "\n" . $tmp[$offset];
                                break;

                                case 'after':
                                $offset = ($lineNum + $mod['search']->offset > $lineMax) ? $lineMax : $lineNum + $mod['search']->offset;
                                $tmp[$offset] = $tmp[$offset] . "\n" . $mod['add']->getContent();
                                break;

                                default:
                                if(!empty($mod['search']->offset)) {
                                    for($i = 1; $i <= $mod['search']->offset; $i++) {
                                        if(isset($tmp[$lineNum + $i])) {
                                            $tmp[$lineNum + $i] = '';
                                        }
                                    }
                                }

                                if($mod['search']->regex == 'true') {
                                    $tmp[$lineNum] = preg_replace($mod['search']->getContent(), $mod['add']->getContent(), $line);
                                } else {
                                    $tmp[$lineNum] = str_replace($mod['search']->getContent(), $mod['add']->getContent(), $line);
                                }
                                break;
                            }
                        }
                    }
                }

                if(!$changed) {
                    $skip = ($mod['error'] == 'skip' || $mod['error'] == 'log') ? ' (SKIPPED)' : ' (ABORTING MOD)';

                    if($mod['error'] == 'log' || $mod['error'] == 'abort') {
                        $this->_vqmod->log->write('SEARCH NOT FOUND' . $skip . ': ' . $mod['search']->getContent(), $this);
                    }

                    if($mod['error'] == 'abort') {
                        $this->_skip = true;
                        return;
                    }

                }

                break;
            }
            ksort($tmp);
            $tmp = $this->_implodeData($tmp);
        }

        $data = $tmp;
    }

    /**
     * VQModObject::_parseMods()
     *
     * @param DOMNode $node <modification> node to be parsed
     * @return null
     * @description Parses modifications in preparation for the applyMod method to work
     */
    private function _parseMods(DOMNode $node){
        $files = $node->getElementsByTagName('file');

        foreach($files as $file) {
            $fileToMod = $file->getAttribute('name');
            $error = ($file->hasAttribute('error')) ? $file->getAttribute('error') : 'log';
            $fullPath = $this->_vqmod->path($fileToMod);

            if(!$fullPath){
                if(strpos($fileToMod, '*') !== false) {
                    $fullPath = $this->_vqmod->getCwd() . $fileToMod;
                } else {
                    if ($error == 'log' || $error == 'abort') {
                        $skip = ($error == 'log') ? ' (SKIPPED)' : ' (ABORTING MOD)';
                        $this->_vqmod->log->write('Could not resolve path for [' . $fileToMod . ']' . $skip, $this);
                    }

                    if ($error == 'log' || $error == 'skip') {
                        continue;
                    } elseif ($error == 'abort') {
                        return false;
                    }
                }
            }

            $operations = $file->getElementsByTagName('operation');

            foreach($operations as $operation) {

                $error = ($operation->hasAttribute('error')) ? $operation->getAttribute('error') : 'abort';

                $this->mods[$fullPath][] = array(
                    'search'        => new VQSearchNode($operation->getElementsByTagName('search')->item(0)),
                    'add'           => new VQAddNode($operation->getElementsByTagName('add')->item(0)),
                    'error'         => $error
                );
            }
        }
    }

    /**
     * VQModObject::_explodeData()
     *
     * @param string $data File contents
     * @return string
     * @description Splits a file into an array of individual lines
     */
    private function _explodeData($data) {
        return explode("\n", $data);
    }

    /**
     * VQModObject::_implodeData()
     *
     * @param array $data Array of lines
     * @return string
     * @description Joins an array of lines back into a text file
     */
    private function _implodeData($data) {
        return implode("\n", $data);
    }
}

/**
 * VQNode
 * @description Basic node object blueprint
 */
class VQNode {
    public $trim = 'false';

    private $_content = '';

    /**
     * VQNode::__construct()
     *
     * @param DOMNode $node Search/add node
     * @return null
     * @description Parses the node attributes and sets the node property
     */
    public function  __construct(DOMNode $node) {
        $this->_content = $node->nodeValue;

        if($node->hasAttributes()) {
            foreach($node->attributes as $attr) {
                $name = $attr->nodeName;
                if(isset($this->$name)) {
                    $this->$name = $attr->nodeValue;
                }
            }
        }
    }

    /**
     * VQNode::getContent()
     *
     * @return string
     * @description Returns the content, trimmed if applicable
     */
    public function getContent() {
        $content = ($this->trim == 'true') ? trim($this->_content) : $this->_content;
        return $content;
    }
}

/**
 * VQSearchNode
 * @description Object for the <search> xml tags
 */
class VQSearchNode extends VQNode {
    public $position = 'replace';
    public $offset = 0;
    public $index = 'false';
    public $regex = 'false';
    public $trim = 'true';

    /**
     * VQSearchNode::indexes()
     *
     * @return bool, array
     * @description Returns the index values to use the search on, or false if none
     */
    public function indexes() {
        if($this->index == 'false') {
            return false;
        }
        $tmp = explode(',', $this->index);
        foreach($tmp as $k => $v) {
            if(!is_int($v)) {
                unset($k);
            }
        }
        $tmp = array_unique($tmp);
        return empty($tmp) ? false : $tmp;
    }
}

/**
 * VQAddNode
 * @description Object for the <add> xml tags
 */
class VQAddNode extends VQNode {
}

Also couple of other ideas to make debugging even easier:

  1. List any other vqmod files which have previously edited this same file.
    This is another common issue where I find when two extensions are editing the same file and the latter is causing the error but it would be useful to know about any other vqmods editing the same file. Yes I suppose I could add error="skip" to everything but dont think this is the best approach to just hide all of the errors, the user should be made aware there is an error…

  2. “Suggested Fix”, maybe some smart way you can test what type of error it is.
    Contradict what I said above but even at its most basic form you could suggest hiding the error if its not essential. So that anybody can read it and understand how it fix it.
    E.g

    OPEN: vqmod/xml/templace.xml (line:23)
    FIND: <operation>
    REPLACE <operation error="skip">
    
  3. Adding the line number in the XML file the error is coming from. It would be lovely not having to search all of the time and could quickly go to the line number in the vqmod

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T14:28:24+00:00Added an answer on June 12, 2026 at 2:28 pm

    The issue for the file being edited is certainly one that is way overdue and one I plan on adding in the next release of vQmod. As for the other suggestions

    1. Interesting idea, and one that could certainly be considered. The only problem I see with this is that it would possibly make some log files enormous
    2. This is going to be next to impossible to incorporate
    3. This is impossible without some pretty expensive runtime. The error doesn’t lie in the XML as such, so would require re-opening the xml that’s been parsed, searching for the line in question line by line and then reporting that. it sounds simple, but you have to remember that xml’s can have the same search parameter for multiple operations – so in that situation you’d be no better off than searching the file yourself
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In Kohana 2 you can override the default error page by creating a custom
Anyone know how to turn off the default error page or where it's referenced??
I just want to see error insteas of asp.net showing me default error Server
Is there a simple way to change the default error values in the jQuery
I am getting a Unable to load the requested file: default.php error in codeigniter
What function to I use to redirect to the default 404 error page? Sample
Rails question. The default behavior for error validation is to fieldWithError-styled div around the
I am getting an error: gpg: no default secret key: No secret key gpg:
When I push a default express app to heroku I get the following error.
So when I deployed the default guestbook application I get a server error. When

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.