$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');
$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; }