Page 1 of 1

Pattern match with PHP API?

Posted: Mon Apr 08, 2013 4:29 pm
by mac86
there is posible to do something like this with API?

:foreach i in=[/queue type find] do={ 
      
      :local uname [/queue type get $i name];  
      :if ( [:pick $uname 0 7] = "pcq_dw_") do={ /queue type remove $i };  
      :if ( [:pick $uname 0 7] = "pcq_up_") do={ /queue type remove $i }; 

}

I've tried something like this without luck :-(
<?php
namespace PEAR2\Net\RouterOS;
require_once 'PEAR2/Autoload.php';

$client = new Client('192.168.10.1', 'api', '1234');


$printRequest = new Request('/queue type print .proplist=.id');
$printRequest->setQuery(Query::where('name', 'pcq_up_*'));     //PATTERN MATCH is possible?
$id = $client->sendSync($printRequest)->getArgument('.id');


$disableRequest = new Request('/queue/type/remove');
$client->sendSync($disableRequest->setArgument('numbers',$id));

// HOW to remove all items?



?>

Re: Pattern match with PHP API?

Posted: Mon Apr 08, 2013 5:06 pm
by boen_robot
Unfortunately, pattern matching is not available in the protocol (yet?), and thus, no client can do it.

You have to do it like you do it in your script equivalent - get ALL queue types, and check their names before you remove them.

In terms of efficiency, it would be better if you first collect the IDs, and remove everything at once afterwards.

So, something like:
<?php
namespace PEAR2\Net\RouterOS;
require_once 'PEAR2/Autoload.php';

$client = new Client('192.168.10.1', 'api', '1234');

$idList = '';
foreach ($client(new Request('/queue type print .proplist=.id,name')) as $entry) {
    if (preg_match('/^pcq\_(up|dw)\_/', $entry->getArgument('name')) {
        $idList .= $entry->getArgument('.id') . ',';
    }
}
$idList = rtrim($idList, ',');

$removeRequest = new Request('/queue/type/remove');
$client->sendSync($removeRequest->setArgument('numbers', $idList)); 

Re: Pattern match with PHP API?

Posted: Mon Apr 08, 2013 5:50 pm
by mac86
Unfortunately, pattern matching is not available in the protocol (yet?), and thus, no client can do it.

You have to do it like you do it in your script equivalent - get ALL queue types, and check their names before you remove them.

In terms of efficiency, it would be better if you first collect the IDs, and remove everything at once afterwards.

So, something like:
<?php
namespace PEAR2\Net\RouterOS;
require_once 'PEAR2/Autoload.php';

$client = new Client('192.168.10.1', 'api', '1234');

$idList = '';
foreach ($client(new Request('/queue type print .proplist=.id,name')) as $entry) {
    if (preg_match('/^pcq\_(up|dw)\_/', $entry->getArgument('name')) {
        $idList .= $entry->getArgument('.id') . ',';
    }
}
$idList = rtrim($idList, ',');

$removeRequest = new Request('/queue/type/remove');
$client->sendSync($removeRequest->setArgument('numbers', $idList)); 
Thank you very much.
I've sent you +1 karma.

Re: Pattern match with PHP API?

Posted: Mon Apr 08, 2013 5:59 pm
by mac86
sorry

I'm not a PHP expert, how ever seem to be a syntax error:
Parse error: syntax error, unexpected '{' in C:\php\pruebas\1.php on line 14
where line 14 is
foreach ($client(new Request('/queue type print .proplist=.id,name')) as $entry) {
sorry for my dumb question.

Re: Pattern match with PHP API?

Posted: Mon Apr 08, 2013 6:05 pm
by boen_robot
I think that might actually be the next line... where I've accidently missed a closing ")""
if (preg_match('/^pcq\_(up|dw)\_/', $entry->getArgument('name')) { 
should instead be
if (preg_match('/^pcq\_(up|dw)\_/', $entry->getArgument('name'))) { 

Re: Pattern match with PHP API?

Posted: Mon Apr 08, 2013 6:11 pm
by mac86
SOLVED !!!

Thank you very much!

Re: Pattern match with PHP API?

Posted: Wed Apr 10, 2013 2:02 am
by mac86
BTW,

if I want to delete all QUEUE SIMPLES, next code works
namespace PEAR2\Net\RouterOS;
require_once 'src/PEAR2/Autoload.php';

$apihost='192.168.10.65';
$apiuser='api';
$apipass='api212223';

$client = new Client($apihost,$apiuser,$apipass); 

$idList = '';
foreach ($client(new Request('/queue simple print .proplist=.id')) as $entry) 
	{
        $idList .= $entry->getArgument('.id') . ',';
}
$idList = rtrim($idList, ',');

$removeRequest = new Request('/queue/simple/remove');
$client->sendSync($removeRequest->setArgument('numbers', $idList)); 

This is equivalent to:
/queue simple remove [/queue simple find]
There is a simpler way to do it with PHP API?

Re: Pattern match with PHP API?

Posted: Wed Apr 10, 2013 12:49 pm
by janisk
you can add comma seperated list of .id values

for example

/queue/simple/remove
=.id=*1,*2,*a,*beef

note that there are no spaces

Re: Pattern match with PHP API?

Posted: Wed Apr 10, 2013 2:45 pm
by boen_robot
There's no simpler way, protocol wise.

I'm thinking of maybe in the next version of my client, implement something among the lines of:
$client = new Client('192.168.10.1', 'api', '1234');
$util = new Util($client);

//Remove all simple queues (same as "/queue simple remove [/queue simple find]")
$util->remove('/queue/simple');

//Remove all queue types of kind "pfifo"
$util->remove('/queue/type', Query::where('kind', 'pfifo'));

//Remove all queue types where the function returns true, i.e. all matching the pattern
$util->remove('/queue/type', function($entry) {
    return preg_match('/^pcq\_(up|dw)\_/', $entry->getArgument('name'));
});

//Remove the entry at index 0, same as how you do it in terminal.
//In order for this to happen, all entries are printed out, sorted by their ID, and only then is the according entry removed...
//Yes, this is a very inefficient option.
$util->remove('/queue/type', 0); 
Would you say that's simpler?

you can add comma seperated list of .id values

for example

/queue/simple/remove
=.id=*1,*2,*a,*beef

note that there are no spaces
That's exactly what's happening with the above code - a comma separated list is generated, and all are deleted at once.

Re: Pattern match with PHP API?

Posted: Wed Apr 10, 2013 3:05 pm
by mac86
I mean if there is a simple way to do this:
/queue simple remove [/queue simple find]
in order to remove all queue simples (without pattern match)


using "getall" api resource maybe?

Re: Pattern match with PHP API?

Posted: Wed Apr 10, 2013 6:53 pm
by boen_robot
I mean if there is a simple way to do this:
/queue simple remove [/queue simple find]
Like I said - No. There is no simple way to do this. At least not currently.

The above examples are what I could do as a simpler way - if you think that is a simpler way. "Under the hood", what will happen is the very thing the first codes above are doing, but it will be fewer lines of code from your point of view.

Re: Pattern match with PHP API?

Posted: Thu Apr 11, 2013 2:54 am
by mac86
I mean if there is a simple way to do this:
/queue simple remove [/queue simple find]
Like I said - No. There is no simple way to do this. At least not currently.

The above examples are what I could do as a simpler way - if you think that is a simpler way. "Under the hood", what will happen is the very thing the first codes above are doing, but it will be fewer lines of code from your point of view.
AGAIN: Thank you very much !!

Re: Pattern match with PHP API?

Posted: Thu Apr 18, 2013 7:00 pm
by jparg
hi, how can i get the answer of the mikrotik?

i use:

$setRequest = new Request('/ip/firewall/address-list/remove');
$setRequest->setArgument('numbers', $id);
$setRequest->setTag('11');
$client->sendAsync($setRequest);

but, i need that the mikrotik send my an answer like "!done *** " or "!trap ***"

Thank You.

Re: Pattern match with PHP API?

Posted: Thu Apr 18, 2013 7:20 pm
by boen_robot
completeRequest() or loop(), followed by extractNewResponses().

- completeRequest() gives you all responses of the specified request (while simultaneously receiving responses to other requests). e.g.
$setRequest = new Request('/ip/firewall/address-list/remove');
$setRequest->setArgument('numbers', $id);
$setRequest->setTag('11');
$client->sendAsync($setRequest);

//Other sendAsync() calls here

$responses = $client->completeRequest('11');
//$responses contains every response of the "11" request   
- extractNewResponses() gives you everything received within a time limit specified at loop() (or, if completeRequest() was called for another request - everything that was received for that other request back then). e.g.
$setRequest = new Request('/ip/firewall/address-list/remove');
$setRequest->setArgument('numbers', $id);
$setRequest->setTag('11');
$client->sendAsync($setRequest);

//Other sendAsync() calls here

$client->loop(4);
$responses1 = $client->extractNewResponses('11');
//$responses1 contains every response of the "11" request that the router gave in the past 4 seconds

$client->loop(3);
$responses2 = $client->extractNewResponses('11');
//$responses1 contains every response of the "11" request received in the last 3 seconds, not including those that the last extractNewResponses() call returned.   
If all you need is to have a request, and process its responses immediately, it's easier if you just use sendSync() instead of sendAsync(). e.g.
$setRequest = new Request('/ip/firewall/address-list/remove');
$setRequest->setArgument('numbers', $id);
$setRequest->setTag('11');
$responses = $client->sendSync($setRequest);
//$responses contains every response of the "11" request   
BTW, you can also use a callback for each response (which would be my personal preference on most occasions) instead of processing the full collection, e.g.
$setRequest = new Request('/ip/firewall/address-list/remove');
$setRequest->setArgument('numbers', $id);
$setRequest->setTag('11');
$client->sendAsync($setRequest, function($response) {
    //Process each response here
});
$client->completeRequest('11');//Start receiving all responses for "11", with each one of them executing the callback above.  

Re: Pattern match with PHP API?

Posted: Thu Apr 18, 2013 7:50 pm
by jparg
ok, thank you.

If i want to print the text in php, how can i do?

Re: Pattern match with PHP API?

Posted: Thu Apr 18, 2013 8:01 pm
by boen_robot
Print what text?

If it's a property, you can use the getArgument() method, and if it's the type, you can use getType(). If you want to print every property, as opposed to just a particular one, you can use getAllArguments(), e.g.
foreach ($responses as $response) {
    echo $response->getType(), "\n";
    foreach ($response->getAllArguments() as $name => $value) {
        echo "={$name}={$value}\n";
    }
    echo '.tag=', $response->getTag();
    foreach ($response->getUnrecognizedWords() as $word) {
        echo $word, "\n";
    }
}