$w->setOption('multiple', true);
$t->like($w->render('foo'), '/<select name="foo\\[\\]" multiple="multiple" id="foo">/', '->render() adds a multiple attribute for multiple selects');
$w->setOption('expanded', true);
$t->like($w->render('foo'), '/<ul class="checkbox_list">/', '->render() uses a checkbox list when expanded and multiple are true');
$w->setOption('multiple', false);
$t->like($w->render('foo'), '/<ul class="radio_list">/', '->render() uses a checkbox list when expanded is true and multiple is false');
// choices are translated
$t->diag('choices are translated');
$ws = new sfWidgetFormSchema();
$ws->addFormFormatter('stub', new FormFormatterStub());
$ws->setFormFormatterName('stub');
$w = new sfWidgetFormChoice(array('choices' => array('foo' => 'bar', 'foobar' => 'foo')));
$w->setParent($ws);
$dom->loadHTML($w->render('foo'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#foo option[value="foo"]')->getValue(), 'translation[bar]', '->render() translates the options');
$t->is($css->matchSingle('#foo option[value="foobar"]')->getValue(), 'translation[foo]', '->render() translates the options');
// ->getJavaScripts() ->getStylesheets()
$t->diag('->getJavaScripts() ->getStylesheets()');
$w = new sfWidgetFormChoice(array('choices' => array()));
$w->setOption('renderer_class', 'MyWidget');
$t->is($w->getJavaScripts(), array('/path/to/a/file.js'), '->getJavaScripts() returns the stylesheets of the renderer widget');
$t->is($w->getStylesheets(), array('/path/to/a/file.css' => 'all'), '->getStylesheets() returns the JavaScripts of the renderer widget');
// __clone()
$t->diag('__clone()');
$w = new sfWidgetFormChoice(array('choices' => new sfCallable(array($w, 'foo'))));
$w1 = clone $w;
$callable = $w1->getOption('choices')->getCallable();
$t->is(spl_object_hash($callable[0]), spl_object_hash($w1), '__clone() changes the choices is a callable and the object is an instance of the current object');
$w = new sfWidgetFormChoice(array('choices' => new sfCallable(array($a = new stdClass(), 'foo'))));
$w1 = clone $w;
$t->diag('->configure()');
try {
    new sfWidgetFormI18nChoiceCountry(array('culture' => 'en', 'countries' => array('EN')));
    $t->fail('->configure() throws an InvalidArgumentException if a country does not exist');
} catch (InvalidArgumentException $e) {
    $t->pass('->configure() throws an InvalidArgumentException if a country does not exist');
}
$v = new sfWidgetFormI18nChoiceCountry(array('culture' => 'en', 'countries' => array('FR', 'GB')));
$t->is(array_keys($v->getOption('choices')), array('FR', 'GB'), '->configure() can restrict the number of countries with the countries option');
// ->render()
$t->diag('->render()');
$w = new sfWidgetFormI18nChoiceCountry(array('culture' => 'fr'));
$dom->loadHTML($w->render('country', 'FR'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#country option[value="FR"]')->getValue(), 'France', '->render() renders all countries as option tags');
$t->is(count($css->matchAll('#country option[value="FR"][selected="selected"]')->getNodes()), 1, '->render() renders all countries as option tags');
// Test for ICU Upgrade and Ticket #7988
// should be 0. Tests will break after ICU Update, which is fine. change count to 0
$t->is(count($css->matchAll('#country option[value="ZZ"]')), 1, '->render() does not contain dummy data');
$t->is(count($css->matchAll('#country option[value="419"]')), 0, '->render() does not contain region data');
// add_empty
$t->diag('add_empty');
$w = new sfWidgetFormI18nChoiceCountry(array('culture' => 'fr', 'add_empty' => true));
$dom->loadHTML($w->render('country', 'FR'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#country option[value=""]')->getValue(), '', '->render() renders an empty option if add_empty is true');
$w = new sfWidgetFormI18nChoiceCountry(array('culture' => 'fr', 'add_empty' => 'foo'));
$dom->loadHTML($w->render('country', 'FR'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#country option[value=""]')->getValue(), 'foo', '->render() renders an empty option if add_empty is true');
$t->is($c->matchAll('#simplelist li:first-child')->getValues(), array('First', 'First'), '->matchAll() :first-child');
$t->is($c->matchAll('#simplelist li:nth-child(1)')->getValues(), array('First', 'First'), '->matchAll() :nth-child');
$t->is($c->matchAll('#simplelist li:nth-child(2)')->getValues(), array('Second with a link', 'Second'), '->matchAll() :nth-child');
$t->is($c->matchAll('#simplelist li:nth-child(3)')->getValues(), array('Third with another link'), '->matchAll() :nth-child');
$t->is($c->matchAll('#simplelist li:last-child')->getValues(), array('Second with a link', 'Third with another link'), '->matchAll() :last-child');
$t->diag('combinations of pseudo-selectors');
$t->is($c->matchAll('.myfoo:contains("myfoo"):contains("bis")')->getValues(), array('myfoo bis'), '->matchAll() :contains():contains()');
$t->is($c->matchAll('.myfoo:contains("myfoo"):last')->getValues(), array('myfoo bis'), '->matchAll() :contains():last');
$t->is($c->matchAll('.myfoo:last:contains("foobarbaz")')->getValues(), array(), '->matchAll() :last:contains()');
$t->is($c->matchAll('.myfoo:contains("myfoo"):contains(\'bis\'):contains(foo)')->getValues(), array('myfoo bis'), '->matchAll() :contains() supports different quote styles');
// ->matchAll()
$t->diag('->matchAll()');
$t->is($c->matchAll('ul')->matchAll('li')->getValues(), $c->matchAll('ul li')->getValues(), '->matchAll() returns a new sfDomCssSelector restricted to the result nodes');
// ->matchSingle()
$t->diag('->matchSingle()');
$t->is(array($c->matchAll('ul li')->getValue()), $c->matchSingle('ul li')->getValues(), '->matchSingle() returns a new sfDomCssSelector restricted to the first result node');
// ->getValues()
$t->diag('->getValues()');
$t->is($c->matchAll('p.myfoo')->getValues(), array('myfoo', 'myfoo bis'), '->getValues() returns all node values');
// ->getValue()
$t->diag('->getValue()');
$t->is($c->matchAll('h1')->getValue(), 'Test page', '->getValue() returns the first node value');
$t->is($c->matchAll('#adjacent_bug > p')->getValues(), array('First paragraph', 'Second paragraph', 'Third paragraph'), '->matchAll() suppports the + combinator');
$t->is($c->matchAll('#adjacent_bug > p > a')->getValues(), array('paragraph'), '->matchAll() suppports the + combinator');
$t->is($c->matchAll('#adjacent_bug p + p')->getValues(), array('Second paragraph', 'Third paragraph'), '->matchAll() suppports the + combinator');
$t->is($c->matchAll('#adjacent_bug > p + p')->getValues(), array('Second paragraph', 'Third paragraph'), '->matchAll() suppports the + combinator');
$t->is($c->matchAll('#adjacent_bug > p + p > a')->getValues(), array('paragraph'), '->matchAll() suppports the + combinator');
// Iterator interface
$t->diag('Iterator interface');
foreach ($c->matchAll('h2') as $key => $value) {
    switch ($key) {
 */

require_once(dirname(__FILE__).'/../../bootstrap/unit.php');

class FormFormatterStub extends sfWidgetFormSchemaFormatter
{
  public function __construct() {}

  public function translate($subject, $parameters = array())
  {
    return sprintf('translation[%s]', $subject);
  }
}

$t = new lime_test(1);

$dom = new DomDocument('1.0', 'utf-8');
$dom->validateOnParse = true;

// ->render()
$t->diag('->render()');

$ws = new sfWidgetFormSchema();
$ws->addFormFormatter('stub', new FormFormatterStub());
$ws->setFormFormatterName('stub');
$w = new sfWidgetFormFilterInput();
$w->setParent($ws);
$dom->loadHTML($w->render('foo'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('label[for="foo_is_empty"]')->getValue(), 'translation[is empty]', '->render() translates the empty_label option');
Exemple #5
0
$t->is($css->matchSingle('#foo_month option')->getNode()->nodeValue, 'MONTH', '->configure() can change the empty values');
$t->is($css->matchSingle('#foo_day option')->getNode()->nodeValue, 'DAY', '->configure() can change the empty values');
$w->setOption('empty_values', array('year' => '', 'month' => '', 'day' => ''));
// format option
$t->diag('format option');
$t->is($css->matchSingle('#foo_day')->getNode()->nextSibling->nodeValue, '/', '->render() renders 3 selects with a default / as a separator');
$t->like($css->matchSingle('#foo_month')->getNode()->nextSibling->nodeValue, '#^/#', '->render() renders 3 selects with a default / as a separator');
$w->setOption('format', '%month%#%day%#%year%');
$dom->loadHTML($w->render('foo', $year . '-10-15'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#foo_day')->getNode()->nextSibling->nodeValue, '#', '__construct() can change the default date format');
$t->like($css->matchSingle('#foo_month')->getNode()->nextSibling->nodeValue, '/^#/', '__construct() can change the default date format');
$w->setOption('format', '%day%/%month%/%year%');
$dom->loadHTML($w->render('foo', $year . '-10-15'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('select')->getNode()->getAttribute('name'), 'foo[day]', '__construct() can change the default date format');
// days / months / years options
$t->diag('days / months / years options');
$w->setOption('years', array(1998 => 1998, 1999 => 1999, 2000 => 2000, 2001 => 2001));
$w->setOption('months', array(1 => 1, 2 => 2, 3 => 3));
$w->setOption('days', array(1 => 1, 2 => 2));
$dom->loadHTML($w->render('foo', $year . '-10-15'));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('#foo_year option')->getNodes()), 5, '__construct() can change the default array used for years');
$t->is(count($css->matchAll('#foo_month option')->getNodes()), 4, '__construct() can change the default array used for months');
$t->is(count($css->matchAll('#foo_day option')->getNodes()), 3, '__construct() can change the default array used for days');
// attributes
$t->diag('attributes');
$dom->loadHTML($w->render('foo', $year . '-10-15', array('disabled' => 'disabled')));
$t->is(count($css->matchAll('select[disabled="disabled"]')->getNodes()), 3, '->render() takes the attributes into account for all the three embedded widgets');
$w->setAttribute('disabled', 'disabled');
$w->setOption('seconds', array(15 => 15, 30 => 30, 45 => 45));
$dom->loadHTML($w->render('foo', '12:30:35'));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('#foo_hour option')->getNodes()), 5, '__construct() can change the default array used for hours');
$t->is(count($css->matchAll('#foo_minute option')->getNodes()), 3, '__construct() can change the default array used for minutes');
$t->is(count($css->matchAll('#foo_second option')->getNodes()), 4, '__construct() can change the default array used for seconds');
// with_seconds option
$t->diag('with_seconds option');
$w->setOption('with_seconds', false);
$dom->loadHTML($w->render('foo', '12:30:35'));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('#foo_second option')->getNodes()), 0, '__construct() can enable or disable the seconds select box with the with_seconds option');
$w->setOption('format_without_seconds', '%hour%#%minute%');
$dom->loadHTML($w->render('foo', '12:30:35'));
$css = new sfDomCssSelector($dom);
$t->like($css->matchSingle('#foo_hour')->getNode()->nextSibling->nodeValue, '/^#/', '__construct() can change the default format');
$t->ok(!count($css->matchSingle('#foo_second')->getNodes()), '__construct() can change the default format');
// attributes
$t->diag('attributes');
$w->setOption('with_seconds', true);
$dom->loadHTML($w->render('foo', '12:30:35', array('disabled' => 'disabled')));
$t->is(count($css->matchAll('select[disabled="disabled"]')->getNodes()), 3, '->render() takes the attributes into account for all the three embedded widgets');
$w->setAttribute('disabled', 'disabled');
$dom->loadHTML($w->render('foo', '12:30:35'));
$t->is(count($css->matchAll('select[disabled="disabled"]')->getNodes()), 3, '->render() takes the attributes into account for all the three embedded widgets');
// id_format
$t->diag('id_format');
$w->setOption('with_seconds', true);
$w->setIdFormat('id_%s');
$dom->loadHTML($w->render('foo'));
$t->is(count($css->matchAll('#id_foo_hour')), 1, '->render() uses id_format for hour');
$t->is(count($css->matchAll('#foo_day option')->getNodes()), 32, '->render() renders a select tag for the 31 days in a month');
$t->is(count($css->matchAll('#foo_hour option')->getNodes()), 25, '->render() renders a select tag for the 24 hours in a day');
$t->is(count($css->matchAll('#foo_minute option')->getNodes()), 61, '->render() renders a select tag for the 60 minutes in an hour');
$t->is(count($css->matchAll('#foo_second option')->getNodes()), 61, '->render() renders a select tag for the 60 seconds in a minute');
// date and time format option
$t->diag('date and time format option');
$t->is($css->matchSingle('#foo_day')->getNode()->nextSibling->nodeValue, '/', '->render() renders 3 selects with a default / as a format');
$t->like($css->matchSingle('#foo_month')->getNode()->nextSibling->nodeValue, '#^/#', '->render() renders 3 selects with a default / as a format');
$t->is($css->matchSingle('#foo_hour')->getNode()->nextSibling->nodeValue, ':', '->render() renders 3 selects with a default : as a format');
$t->is($css->matchSingle('#foo_minute')->getNode()->nextSibling->nodeValue, ':', '->render() renders 3 selects with a default : as a format');
$t->diag('change date and time format option');
$w->setOption('date', array('format' => '%month%-%day%-%year%'));
$w->setOption('time', array('format' => '%hour%!%minute%!%second%', 'with_seconds' => true));
$dom->loadHTML($w->render('foo', '2005-10-15 12:30:35'));
$css = new sfDomCssSelector($dom);
$t->is($css->matchSingle('#foo_day')->getNode()->nextSibling->nodeValue, '-', '__construct() can change the default format');
$t->like($css->matchSingle('#foo_month')->getNode()->nextSibling->nodeValue, '/^-/', '__construct() can change the default format');
$t->is($css->matchSingle('#foo_hour')->getNode()->nextSibling->nodeValue, '!', '__construct() can change the default format');
$t->is($css->matchSingle('#foo_minute')->getNode()->nextSibling->nodeValue, '!', '__construct() can change the default format');
// with_time option
$t->diag('with_time option');
$w = new sfWidgetFormDateTime(array('with_time' => false));
$dom->loadHTML($w->render('foo', '2005-10-15 12:30:35'));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('#foo_hour')->getNodes()), 0, '->render() does not render the time if the with_time option is disabled');
// date and time options as array
$t->diag('date and time options as array');
$w = new sfWidgetFormDateTime(array('date' => 'a string'));
try {
    $w->render('foo');
    $t->fail('__construct() throws a InvalidArgumentException if the date/time options is not an array');
$t->is($css->matchSingle('#foo option[value="foobar"][selected="selected"]')->getValue(), 'foo', '->render() renders a select tag with the value selected');
$t->is(count($css->matchAll('#foo option')->getNodes()), 2, '->render() renders all choices as option tags');
// value attribute is always mandatory
$w = new sfWidgetFormSelect(array('choices' => array('' => 'bar')));
$t->like($w->render('foo', 'foobar'), '/<option value="">/', '->render() always generate a value attribute, even for empty keys');
// other attributes are removed is empty
$w = new sfWidgetFormSelect(array('choices' => array('' => 'bar')));
$t->like($w->render('foo', 'foobar', array('class' => '', 'style' => null)), '/<option value="">/', '->render() always generate a value attribute, even for empty keys');
// multiple select
$t->diag('multiple select');
$w = new sfWidgetFormSelect(array('multiple' => true, 'choices' => array('foo' => 'bar', 'foobar' => 'foo')));
$dom->loadHTML($w->render('foo', array('foo', 'foobar')));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('select[multiple="multiple"]')->getNodes()), 1, '->render() automatically adds a multiple HTML attributes if multiple is true');
$t->is(count($css->matchAll('select[name="foo[]"]')->getNodes()), 1, '->render() automatically adds a [] at the end of the name if multiple is true');
$t->is($css->matchSingle('#foo option[value="foobar"][selected="selected"]')->getValue(), 'foo', '->render() renders a select tag with the value selected');
$t->is($css->matchSingle('#foo option[value="foo"][selected="selected"]')->getValue(), 'bar', '->render() renders a select tag with the value selected');
$dom->loadHTML($w->render('foo[]', array('foo', 'foobar')));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('select[name="foo[]"]')->getNodes()), 1, '->render() automatically does not add a [] at the end of the name if multiple is true and the name already has one');
// optgroup support
$t->diag('optgroup support');
$w = new sfWidgetFormSelect(array('choices' => array('foo' => array('foo' => 'bar', 'bar' => 'foo'), 'foobar' => 'foo')));
$dom->loadHTML($w->render('foo', array('foo', 'foobar')));
$css = new sfDomCssSelector($dom);
$t->is(count($css->matchAll('#foo optgroup[label="foo"] option')->getNodes()), 2, '->render() has support for optgroups tags');
try {
    $w = new sfWidgetFormSelect();
    $t->fail('__construct() throws an RuntimeException if you don\'t pass a choices option');
} catch (RuntimeException $e) {
    $t->pass('__construct() throws an RuntimeException if you don\'t pass a choices option');
 */
require_once dirname(__FILE__) . '/../bootstrap.php';
require_once dirname(__FILE__) . '/../../lib/widget/sfWidgetFormReCaptcha.class.php';
require_once $_SERVER['SYMFONY'] . '/util/sfDomCssSelector.class.php';
$t = new lime_test(7, new lime_output_color());
$REMOTE_ADDR = 'symfony.example.com';
$PUBLIC_KEY = '6Lf2DQEAAAAAALB9pGaVdcjMiv4CAuOVkfCSVvGh';
$PRIVATE_KEY = '6Lf2DQEAAAAAALnEL0iEogIxZNYMlG7pmNhwEXjk';
// __construct()
$t->diag('__construct()');
try {
    new sfWidgetFormReCaptcha();
} catch (RuntimeException $e) {
    $t->pass('__construct() expects a "public_key" option');
}
// ->render()
$t->diag('->render()');
$w = new sfWidgetFormReCaptcha(array('public_key' => $PUBLIC_KEY));
$dom = new DomDocument('1.0', 'utf-8');
$dom->loadHTML($w->render('captcha'));
$c = new sfDomCssSelector($dom);
$t->is(count($c->matchSingle('script[src^="http://"]')->getNodes()), 1, '->render() uses the HTTP ReCaptcha URL by default');
$t->is(count($c->matchSingle(sprintf('script[src$="%s"]', $PUBLIC_KEY))->getNodes()), 1, '->render() embeds the ReCatpcha public key in the URL');
$t->is(count($c->matchSingle('iframe[src^="http://"]')->getNodes()), 1, '->render() uses the HTTP ReCaptcha URL by default');
$t->is(count($c->matchSingle(sprintf('iframe[src$="%s"]', $PUBLIC_KEY))->getNodes()), 1, '->render() embeds the ReCatpcha public key in the URL');
$w = new sfWidgetFormReCaptcha(array('public_key' => $PUBLIC_KEY, 'use_ssl' => true));
$dom = new DomDocument('1.0', 'utf-8');
$dom->loadHTML($w->render('captcha'));
$c = new sfDomCssSelector($dom);
$t->is(count($c->matchSingle('script[src^="https://"]')->getNodes()), 1, '->render() uses the HTTPS ReCaptcha URL is use_ssl is true');
$t->is(count($c->matchSingle('iframe[src^="https://"]')->getNodes()), 1, '->render() uses the HTTPS ReCaptcha URL is use_ssl is true');
 public function getForm4Urls()
 {
     //to check out the page, an example url: http://searchwww.sec.gov/EDGARFSClient/jsp/EDGAR_Query_Result.jsp?queryString=&queryForm=Form4&isAdv=1&queryCik=876437&numResults=100#topAnchor
     $types = array('Form3', 'Form4');
     $form4_urls = array();
     $unique_ciks = array();
     foreach ($types as $type) {
         $search_pages = 0;
         $next_page = true;
         $url = 'http://searchwww.sec.gov/EDGARFSClient/jsp/EDGAR_MainAccess.jsp?search_text=*&sort=Date&formType=' . $type . '&isAdv=true&stemming=true&numResults=100&queryCik=' . $this->entity->sec_cik . '&fromDate=01/01/' . strval($this->years[0]) . '&toDate=01/01/' . strval($this->years[count($this->years) - 1] + 1);
         $this->printDebug("Form 3/4 search url: " . $url);
         //loop through search results
         while ($next_page == true && $search_pages < $this->search_depth) {
             if (!$this->browser->get($url)->responseIsError()) {
                 $selector = $this->browser->getResponseDomCssSelector();
                 $text = $this->browser->getResponseText();
                 $rows = $selector->matchAll('tr')->getNodes();
                 for ($i = 0; $i < count($rows); $i++) {
                     $row = new sfDomCssSelector(array($rows[$i]));
                     $links = $row->matchAll('a')->getNodes();
                     $person_cik = null;
                     foreach ($links as $link) {
                         if ($link->getAttribute('name') == 'cikSearch') {
                             $cik = trim($link->textContent);
                             //break if it's the same as corp's cik
                             if ($cik != $this->entity->sec_cik) {
                                 $person_cik = $cik;
                                 break;
                             }
                         }
                     }
                     if (!$person_cik) {
                         continue;
                     }
                     if (!in_array($person_cik, $unique_ciks)) {
                         $prev_row = new sfDomCssSelector($rows[$i - 1]);
                         if (!is_object($href = $prev_row->matchSingle('a')->getNode())) {
                             continue;
                         }
                         $href = $href->getAttribute('href');
                         //if not an xml doc, grab the parent filing underneath the listing
                         if (!stripos($href, '.xml')) {
                             $next_row = new sfDomCssSelector($rows[$i + 2]);
                             if (!is_object($href = $next_row->matchSingle('a')->getNode())) {
                                 continue;
                             }
                             if (trim($href->getAttribute('title')) == 'Parent Filing') {
                                 $href = $href->getAttribute('href');
                             } else {
                                 continue;
                             }
                         }
                         if (preg_match("/\\'([^\\']+)\\'/", $href, $matches)) {
                             $unique_ciks[] = $person_cik;
                             $u = str_replace('xslF345/', '', $matches[1]);
                             if ($u != $matches[1]) {
                                 $form4_urls[] = array('xmlUrl' => $u, 'htmlUrl' => $matches[1], 'readableXmlUrl' => preg_replace('/[^\\/]+\\.xml/i', 'xslF345X03/$0', $u));
                             }
                         }
                     }
                 }
                 $next_page = false;
                 $links = $selector->matchAll('.clsBlueBg')->getNodes();
                 foreach ($links as $link) {
                     if ($link->getAttribute('title') == "Next Page") {
                         $url = "http://searchwww.sec.gov" . $link->getAttribute('href');
                         $next_page = true;
                     }
                 }
             }
             $search_pages++;
         }
     }
     return $form4_urls;
 }
 private function getForm4Urls($corp_cik)
 {
     //to check out the page, an example url: http://searchwww.sec.gov/EDGARFSClient/jsp/EDGAR_Query_Result.jsp?queryString=&queryForm=Form4&isAdv=1&queryCik=876437&numResults=100#topAnchor
     $url = 'http://searchwww.sec.gov/EDGARFSClient/jsp/EDGAR_Query_Result.jsp?queryString=&queryForm=Form4&isAdv=1&queryCik=' . $corp_cik . '&numResults=10';
     $form4_urls = array();
     $search_pages = 0;
     $unique_ciks = array();
     $next_page = true;
     //loop through search results
     while ($next_page == true && $search_pages < $this->search_depth) {
         if (!$this->browser->get($url)->responseIsError()) {
             $selector = $this->browser->getResponseDomCssSelector();
             $text = $this->browser->getResponseText();
             $rows = $selector->matchAll('tr')->getNodes();
             for ($i = 0; $i < count($rows); $i++) {
                 $row = new sfDomCssSelector(array($rows[$i]));
                 $links = $row->matchAll('a')->getNodes();
                 $person_cik = null;
                 foreach ($links as $link) {
                     if ($link->getAttribute('name') == 'cikSearch') {
                         $person_cik = trim($link->textContent);
                         //break if it's not same as corp's cik
                         if ($person_cik != $corp_cik) {
                             break;
                         }
                     }
                 }
                 if (!$person_cik) {
                     continue;
                 }
                 if (!in_array($person_cik, $unique_ciks)) {
                     $prev_row = new sfDomCssSelector($rows[$i - 1]);
                     $href = $prev_row->matchSingle('a')->getNode();
                     if (!is_object($href)) {
                         continue;
                     }
                     $href = $href->getAttribute('href');
                     //if not an xml doc, grab the parent filing underneath the listing
                     if (!stripos($href, '.xml')) {
                         $next_row = new sfDomCssSelector($rows[$i + 2]);
                         $href = $next_row->matchSingle('a')->getNode();
                         if (!is_object($href)) {
                             continue;
                         }
                         if (trim($href->getAttribute('title')) == 'Parent Filing') {
                             $href = $href->getAttribute('href');
                         } else {
                             continue;
                         }
                     }
                     if (preg_match("/\\'([^\\']+)\\'/", $href, $matches)) {
                         $unique_ciks[] = $person_cik;
                         $u = str_replace('xslF345/', '', $matches[1]);
                         if ($u != $matches[1]) {
                             $form4_urls[] = array('xmlUrl' => $u, 'htmlUrl' => $matches[1]);
                         }
                     }
                 }
             }
             $next_page = false;
             $links = $selector->matchAll('.clsBlueBg')->getNodes();
             foreach ($links as $link) {
                 if ($link->getAttribute('title') == "Next Page") {
                     $url = "http://searchwww.sec.gov" . $link->getAttribute('href');
                     $next_page = true;
                 }
             }
         }
         $search_pages++;
     }
     return $form4_urls;
 }