Search code examples
phpvqmod

vqmod advanced search by searching twice


I am faced with a problem where I need to search for a line of code which is too common.

Say I have this code and need to convert it into an array_merge:

$this['data'][] = array(
    'firstname'      => $query->row['firstname'],
    'lastname'       => $query->row['lastname'],
    'company'        => $query->row['company'],
    'company_id'     => $query->row['company_id']
);

vqmod

<operation>
    <search position="replace"><![CDATA[
    $this['data'][] = array( ]]></search>
    <add><![CDATA[
    $this['data'][] = array_merge($data, array( ]]></add>
</operation>
<operation>
    <search position="replace"><![CDATA[
    ); ]]></search>
    <add><![CDATA[
    )); ]]></add>
</operation>

Problem with this is that it's trying to search for code which is too common.

I could use offset to replace the whole thing because we use other extensions modifying this same array. Also can't rely that company_id is always last.

So instead I was thinking if there was a way to search twice or something similar to this concept:

  1. Search for: $this['data'][] = array( find the line number of this.
  2. Then start the next search from this line number, finding the next occurrence of: );

This same idea could then be applied to a method where I wanted to add some logic before the returned data.

<operation>
    <search position="before"><![CDATA[
    private static function _cacheName ]]></search>
    <search2><![CDATA[
    return ]]></search2>
    <add><![CDATA[
    // custom code ]]></add>
</operation>

Solution

  • You can use index. As stated in the vqmod's Scripting manual, you can specify which results you'd like to use. So the code below would find the 2nd occurrence of the text and replace it with the specified part:

    <operation>
      <search position="replace" index="2"><![CDATA[
      $this['data'][] = array( ]]></search>
      <add><![CDATA[
      $this['data'][] = array_merge($data, array(]]></add>
    </operation>
    

    You can apply the same thing to the closing );. Alternatively, you could try to figure out how many lines are within that array, and you could use an offset with replace:

    <operation>
      <search position="replace" index="2" offset="4"><![CDATA[
      $this['data'][] = array( ]]></search>
      <add><![CDATA[
      ));]]></add>
    </operation>
    

    A good starting point would be to check the file which is modified, in the vqcache folder, so you would have an idea on how many lines shall you offset.

    It's important to note, that vqmod can only search for a single line or a part of a single line.