/** * @param Net_LDAP2_Entry $entry * @param string $field * @return string */ private function Get($entry, $field) { $actualField = $field; if (array_key_exists($field, $this->mapping)) { $actualField = $this->mapping[$field]; } $value = $entry->getValue($actualField); if (is_array($value)) { return $value[0]; } return $value; }
/** * Parse LDIF lines of one entry into an Net_LDAP2_Entry object * * @param array $lines LDIF lines for one entry * * @return Net_LDAP2_Entry|false Net_LDAP2_Entry object for those lines * @todo what about file inclusions and urls? "jpegphoto:< file:///usr/local/directory/photos/fiona.jpg" */ public function parseLines($lines) { // parse lines into an array of attributes and build the entry $attributes = array(); $dn = false; foreach ($lines as $line) { if (preg_match('/^(\\w+)(:|::|:<)\\s(.+)$/', $line, $matches)) { $attr =& $matches[1]; $delim =& $matches[2]; $data =& $matches[3]; if ($delim == ':') { // normal data $attributes[$attr][] = $data; } elseif ($delim == '::') { // base64 data $attributes[$attr][] = base64_decode($data); } elseif ($delim == ':<') { // file inclusion // TODO: Is this the job of the LDAP-client or the server? $this->dropError('File inclusions are currently not supported'); //$attributes[$attr][] = ...; } else { // since the pattern above, the delimeter cannot be something else. $this->dropError('Net_LDAP2_LDIF parsing error: invalid syntax at parsing entry line: ' . $line); continue; } if (strtolower($attr) == 'dn') { // DN line detected $dn = $attributes[$attr][0]; // save possibly decoded DN unset($attributes[$attr]); // remove wrongly added "dn: " attribute } } else { // line not in "attr: value" format -> ignore // maybe we should rise an error here, but this should be covered by // next_lines() already. A problem arises, if users try to feed data of // several entries to this method - the resulting entry will // get wrong attributes. However, this is already mentioned in the // methods documentation above. } } if (false === $dn) { $this->dropError('Net_LDAP2_LDIF parsing error: unable to detect DN for entry'); return false; } else { $newentry = Net_LDAP2_Entry::createFresh($dn, $attributes); return $newentry; } }
/** * @todo Implement testGetValue(). */ public function testGetValue() { // make up some local entry $entry = Net_LDAP2_Entry::createFresh("cn=test", array('attr1' => 'single', 'attr2' => array('mv1', 'mv2'))); // test default behavior $this->assertEquals('single', $entry->getValue('attr1')); $this->assertEquals(array('mv1', 'mv2'), $entry->getValue('attr2')); $this->assertEquals(false, $entry->getValue('nonexistent')); // test option "single" $this->assertEquals('single', $entry->getValue('attr1', 'single')); $this->assertEquals('mv1', $entry->getValue('attr2', 'single')); $this->assertEquals(false, $entry->getValue('nonexistent', 'single')); // test option "all" $this->assertEquals(array('single'), $entry->getValue('attr1', 'all')); $this->assertEquals(array('mv1', 'mv2'), $entry->getValue('attr2', 'all')); $this->assertEquals(array(), $entry->getValue('nonexistent', 'all')); }
/** * Get the next entry in the searchresult. * * This will return a valid Net_LDAP2_Entry object or false, so * you can use this method to easily iterate over the entries inside * a while loop. * * @return Net_LDAP2_Entry|false Reference to Net_LDAP2_Entry object or false */ public function &shiftEntry() { if ($this->count() == 0) { $false = false; return $false; } if (is_null($this->_entry)) { $this->_entry = @ldap_first_entry($this->_link, $this->_search); $entry = Net_LDAP2_Entry::createConnected($this->_ldap, $this->_entry); if ($entry instanceof Net_LDAP2_Error) { $entry = false; } } else { if (!($this->_entry = @ldap_next_entry($this->_link, $this->_entry))) { $false = false; return $false; } $entry = Net_LDAP2_Entry::createConnected($this->_ldap, $this->_entry); if ($entry instanceof Net_LDAP2_Error) { $entry = false; } } return $entry; }
/** * Creates an Net_LDAP2_Entry object that is considered already existing * * Use this method, if you want to modify an already existing entry * without fetching it first. * In most cases however, it is better to fetch the entry via Net_LDAP2->getEntry()! * * Please note that you should take care if you construct entries manually with this * because you may get weird synchronisation problems. * The attributes and values as well as the entry itself are considered existent * which may produce errors if you try to modify an entry which doesn't really exist * or if you try to overwrite some attribute with an value already present. * * This method is equal to calling createFresh() and after that markAsNew(FALSE). * * The method should be called statically: $entry = Net_LDAP2_Entry::createExisting(); * * The attributes parameter is as following: * <code> * $attrs = array( 'attribute1' => array('value1', 'value2'), * 'attribute2' => 'single value' * ); * </code> * * @param string $dn DN of the Entry * @param array $attrs Attributes of the entry * * @static * @return Net_LDAP2_Entry|Net_LDAP2_Error */ public static function createExisting($dn, $attrs = array()) { if (!is_array($attrs)) { return PEAR::raiseError("Unable to create entry object: Parameter \$attrs needs to be an array!"); } $entry = Net_LDAP2_Entry::createFresh($dn, $attrs); if ($entry instanceof Net_LDAP2_Error) { return $entry; } else { $entry->markAsNew(false); return $entry; } }
/** * Copy an entry to a new location * * The entry will be immediately copied. * Please note that only attributes you have * selected will be copied. * * @param Net_LDAP2_Entry &$entry Entry object * @param string $newdn New FQF-DN of the entry * * @return Net_LDAP2_Error|Net_LDAP2_Entry Error Message or reference to the copied entry */ public function ©(&$entry, $newdn) { if (!$entry instanceof Net_LDAP2_Entry) { return PEAR::raiseError('Parameter $entry is expected to be a Net_LDAP2_Entry object!'); } $newentry = Net_LDAP2_Entry::createFresh($newdn, $entry->getValues()); $result = $this->add($newentry); if ($result instanceof Net_LDAP2_Error) { return $result; } else { return $newentry; } }
if ($r === NULL) { fail("searchUser {$token}", "invalid response\n{$js}"); } $got = map_obj_attr($r, 'uid'); expectToBe(json_encode($got), $expected, "searchUser {$token}"); } searchUser('Fooo Bar', '["fbar"]'); searchUser('o Bar', '["fbar","zbar"]'); searchUser('Fooo B', '["fbar"]'); searchUser('Fooo ', '["fbar"]'); searchUser('Fooo', '["fbar"]'); searchUser('Foo', '[]'); // no sub search if short token searchUser('Bar Fooo', '["fbar"]'); searchUser('Bar Foo', '["fbar"]'); searchUser('Bar', '["fbar","zbar"]'); // exact search on sn searchUser('99007', '["fbar"]'); // exact search on sn Xexpect('getSuperGroups structures', '{"diploma-L2T101":{"key":"diploma-L2T101","description":"L2T101 - Licence 1\\u00e8re ann\\u00e9e Droit (FC)","rawKey":"L2T101","name":"L2T101 - Licence 1\\u00e8re ann\\u00e9e Droit (FC)","category":"diploma","superGroups":[]}}', 'getSuperGroups', ['key' => 'structures-DGH']); $allGroups = <<<'EOS' [{"key":"groups-employees.administration.DGH","name":"employees.administration.DGH"},{"key":"groups-employees.administration.DGHA","name":"DSIUN-SAS : Service des applications et services num\u00e9riques","description":"employees.administration.DGH"},{"key":"groups-matiB1010514","name":"UFR 02 - Mati\u00e8re (Semestre 1) : Comptabilit\u00e9 d'entreprise","description":"<br>\n<br>\n<br>\n"},{"key":"affiliation-faculty","name":"Tous les enseignants","description":"Tous les enseignants"},{"key":"affiliation-teacher","name":"Tous les enseignants et charg\u00e9s d'enseignement","description":"Tous les enseignants et charg\u00e9s d'enseignement"},{"key":"affiliation-student","name":"Tous les \u00e9tudiants","description":"Tous les \u00e9tudiants"},{"key":"affiliation-staff","name":"Tous les Biatss","description":"Tous les Biatss"},{"key":"affiliation-researcher","name":"Tous les chercheurs","description":"Tous les chercheurs"},{"key":"affiliation-emeritus","name":"Tous les professeurs \u00e9m\u00e9rites","description":"Tous les professeurs \u00e9m\u00e9rites"},{"key":"affiliation-affiliate","name":"Tous les invit\u00e9s","description":"Tous les invit\u00e9s"},{"key":"businessCategory-research","name":"Laboratoires de recherche","description":"Laboratoires de recherche"},{"key":"businessCategory-library","name":"Biblioth\u00e8ques","description":"Biblioth\u00e8ques"},{"key":"businessCategory-doctoralSchool","name":"\u00c9coles doctorales","description":"\u00c9coles doctorales"},{"key":"businessCategory-administration","name":"Services","description":"Services"},{"key":"businessCategory-pedagogy","name":"Composantes personnels","description":"Composantes personnels"}] EOS; Xexpect('allGroups', $allGroups, 'allGroups', []); if (0) { $dn = 'uid=foo,dc=fr'; $entry = Net_LDAP2_Entry::createFresh($dn); $entry->add(array('entryDN' => $entry->dn())); $filter = Net_LDAP2_Filter::parse("(entryDN={$dn})"); var_dump($filter->matches($entry)); }
/** * Test match() */ public function testMatch() { // make up some local test entry $entry1 = Net_LDAP2_Entry::createFresh('cn=Simpson Homer,l=springfield,c=usa', array('cn' => 'Simpson Homer', 'sn' => 'Simpson', 'givenName' => 'Homer', 'fingers' => 5, 'hairColor' => 'black', 'donutsConsumed' => 4521875663232, 'height' => '175', 'mail' => '*****@*****.**', 'objectClass' => array('top', 'person', 'inetOrgPerson', 'myFancyTestClass'))); $entry2 = Net_LDAP2_Entry::createFresh('cn=Simpson Bart,l=springfield,c=usa', array('cn' => 'Simpson Bart', 'sn' => 'Simpson', 'givenName' => 'Bart', 'fingers' => 5, 'hairColor' => 'yellow', 'height' => '120', 'mail' => '*****@*****.**', 'objectClass' => array('top', 'person', 'inetOrgPerson', 'myFancyTestClass'))); $entry3 = Net_LDAP2_Entry::createFresh('cn=Brockman Kent,l=springfield,c=usa', array('cn' => 'Brockman Kent', 'sn' => 'Brockman', 'givenName' => 'Kent', 'fingers' => 5, 'hairColor' => 'white', 'height' => '185', 'mail' => '*****@*****.**', 'objectClass' => array('top', 'person', 'inetOrgPerson', 'myFancyTestClass'))); $allEntries = array($entry1, $entry2, $entry3); // Simple matching on single entry $filter = Net_LDAP2_Filter::create('cn', 'equals', 'Simpson Homer'); $this->assertEquals(1, $filter->matches($entry1)); $filter = Net_LDAP2_Filter::create('cn', 'equals', 'son'); $this->assertEquals(0, $filter->matches($entry1)); $filter = Net_LDAP2_Filter::create('mail', 'begins', 'Hom'); $this->assertEquals(1, $filter->matches($entry1)); $filter = Net_LDAP2_Filter::create('objectClass', 'contains', 'org'); // note the lowercase of 'org', as DirSTR is usually syntax CaseIgnore $this->assertEquals(1, $filter->matches($entry1)); // Simple negative tests on single entry $filter = Net_LDAP2_Filter::create('givenName', 'equals', 'Lisa-is-nonexistent'); $this->assertEquals(0, $filter->matches($entry1)); // Simple tests with multiple entries $filter = Net_LDAP2_Filter::create('cn', 'begins', 'Nomatch'); $this->assertEquals(0, $filter->matches($allEntries)); $filter = Net_LDAP2_Filter::create('cn', 'begins', 'Simpson Ho'); $this->assertEquals(1, $filter->matches($allEntries)); $filter = Net_LDAP2_Filter::create('cn', 'begins', 'Simpson'); $this->assertEquals(2, $filter->matches($allEntries)); // test with retrieving the resulting entries $filter = Net_LDAP2_Filter::create('cn', 'begins', 'Simpson Ho'); $filterresult = array(); $this->assertEquals(1, $filter->matches($allEntries, $filterresult)); $this->assertEquals(count($filterresult), $filter->matches($allEntries, $filterresult), "returned result and result counter differ!"); $this->assertEquals($entry1->dn(), array_shift($filterresult)->dn(), "Filtered entry does not equal expected entry! filter='" . $filter->asString() . "'"); // make sure return values are consistent with input and that all entries are found $filter = Net_LDAP2_Filter::parse('(objectClass=*)'); $filterresult = array(); $this->assertEquals(count($allEntries), $filter->matches($allEntries, $filterresult), "returned result does not match input data count"); $this->assertEquals(count($filterresult), $filter->matches($allEntries, $filterresult), "returned result and result counter differ!"); // Test for compliant "any" filtering: // Only entries should be returned, that have the attribute // Negation: Only Entries that don't have the attribute set at all $filter = Net_LDAP2_Filter::create('donutsConsumed', 'any'); // only homer consume donuts $filterresult = array(); $this->assertEquals(1, $filter->matches($allEntries, $filterresult)); $this->assertEquals($entry1->dn(), array_shift($filterresult)->dn(), "Filtered entry does not equal expected entry! filter='" . $filter->asString() . "'"); $filter = Net_LDAP2_Filter::combine('not', $filter); // all but homer consume donuts $this->assertEquals(count($allEntries) - 1, $filter->matches($allEntries, $filterresult), "Filtered entry does not equal expected entry! filter='" . $filter->asString() . "'"); // NOT combination test $filter = Net_LDAP2_Filter::create('givenName', 'not equals', 'Homer'); $filterresult = array(); $this->assertEquals(2, $filter->matches($allEntries, $filterresult)); $this->assertEquals($entry2->dn(), array_shift($filterresult)->dn(), "Filtered entry does not equal expected entry! filter='" . $filter->asString() . "'"); $this->assertEquals($entry3->dn(), array_shift($filterresult)->dn(), "Filtered entry does not equal expected entry! filter='" . $filter->asString() . "'"); // OR combination test $filter1 = Net_LDAP2_Filter::create('sn', 'equals', 'Simpson'); $filter2 = Net_LDAP2_Filter::create('givenName', 'equals', 'Kent'); $filter_or = Net_LDAP2_Filter::combine('or', array($filter1, $filter2)); $filterresult = array(); $this->assertEquals(3, $filter_or->matches($allEntries, $filterresult)); // AND combination test $filter1 = Net_LDAP2_Filter::create('sn', 'equals', 'Simpson'); $filter2 = Net_LDAP2_Filter::create('givenName', 'equals', 'Bart'); $filter_and = Net_LDAP2_Filter::combine('and', array($filter1, $filter2)); $filterresult = array(); $filter_and->matches($allEntries, $filterresult); $this->assertEquals(1, $filter_and->matches($allEntries, $filterresult), "AND Filter failed '" . $filter_and->asString() . "'"); // AND, NOT and OR combined test $filter1 = Net_LDAP2_Filter::combine('or', array(Net_LDAP2_Filter::create('hairColor', 'equals', 'white'), Net_LDAP2_Filter::create('hairColor', 'equals', 'black'))); $filter2 = Net_LDAP2_Filter::create('givenName', 'not equals', 'Homer'); // all except homer $filter_final = Net_LDAP2_Filter::combine('and', array($filter1, $filter2)); $this->assertEquals(2, $filter1->matches($allEntries)); // kent and homer $this->assertEquals(2, $filter2->matches($allEntries)); // kent and bart $filterresult = array(); $this->assertEquals(1, $filter_final->matches($allEntries, $filterresult)); // should leave only kent $this->assertEquals($entry3->dn(), array_shift($filterresult)->dn(), "Filtered entry does not equal expected entry! filter='" . $filter_final->asString() . "'"); // [TODO]: Further tests for >, <, >=, <= and ~=, when they are implemented. // ...until then: negative testing for those cases foreach (array('>', '<', '>=', '<=', '~=') as $to) { $filter = Net_LDAP2_Filter::parse("(fingers{$to}5)"); $this->assertInstanceOf('PEAR_Error', $filter->matches($allEntries), "Valid operator succeeded: WRITE THE TESTCASE FOR IT!"); } }
/** * * @return string */ public function getDn() { return $this->ldapEntry->currentDN(); }
// We must define the DN of the new entry. The DN is the // global unique path to the data in the directory server, // similar to a path name in your filesystem. // Since we want to be a little flexible, we make the base // dynamic, so it is enough to change the base-dn in your // $ldap_config array. $dn = 'cn=Foo Bar,' . $ldap_config['base']; // It is a good idea to first look if the entry, that should be added, // is already present: if ($ldap->dnExists($dn)) { die('Could not add entry! Entry already exists!'); } // The entry does not exist so far, we can safely add him. // But first, we must construct the entry. // This is, because Net_LDAP2 was build to make changes only // locally (in your script), not directly on the server. $attributes = array('sn' => 'Foo', 'gn' => 'Bar', 'mail' => array('*****@*****.**', '*****@*****.**'), 'employeeNumber' => 123456); $new_entry = Net_LDAP2_Entry::createFresh($dn, $attributes); // Finally add the entry in the server: $result = $ldap->add($new_entry); if (Net_LDAP2::isError($result)) { die('Unable to add entry: ' . $result->getMessage()); } // The entry is now present in the directory server. // Additionally, it is linked to the $ldap connection used for the add(), // so you may call $entry->modify() (and friends) and $entry->update() // without the need for passing an $ldap object. // This is only the case if the entry was not linked to an Net_LDAP2 object // before, so if the entry object would be fetched from a $ldap object // and then added to $ldap_2, the link of the entry remains to $ldap, // thus any update() will be performed on directory1 ($ldap).
/** * Test for bug #18202: "Adding attributes to a Fresh Entry saving and laterly updating fails" */ public function testEntryAddIsNotPersistent() { if (!$this->ldapcfg) { $this->markTestSkipped('No ldapconfig.ini found. Skipping test!'); } else { $ldap = $this->connect(); // setup test entry $cn = 'Net_LDAP2_Test_bug_18202'; $dn = 'cn=' . $cn . ',' . $this->ldapcfg['global']['server_base_dn']; $data = array('objectClass' => array('top', 'inetOrgPerson'), 'givenName' => 'bug 18202', 'sn' => 'testentry', 'cn' => $cn); // Test case $entry = Net_LDAP2_Entry::createFresh($dn, $data); $this->assertInstanceOf('Net_LDAP2_Entry', $entry); $this->assertTrue($entry->add(array('uid' => 'Fu Bar'))); $this->assertTrue($ldap->add($entry)); $this->assertTrue($entry->replace(array('uid' => 'Foo Bar'))); $this->assertTrue($result = $entry->update()); // cleanup $this->assertTrue($ldap->delete($entry), 'Cleanup of test entry failed. Please remove manually: ' . $entry->dn()); } }
/** * tests SPL iterator */ public function testSPLIterator() { if (!$this->ldapcfg) { $this->markTestSkipped('No ldapconfig.ini found. Skipping test!'); } else { $ldap = $this->connect(); // some testdata, so we have some entries to search for $base = $this->ldapcfg['global']['server_base_dn']; $ou1 = Net_LDAP2_Entry::createFresh('ou=Net_LDAP2_Test_search1,' . $base, array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Net_LDAP2_Test_search1')); $ou2 = Net_LDAP2_Entry::createFresh('ou=Net_LDAP2_Test_search2,' . $base, array('objectClass' => array('top', 'organizationalUnit'), 'ou' => 'Net_LDAP2_Test_search2')); $this->assertTrue($ldap->add($ou1)); $this->assertTrue($ldap->dnExists($ou1->dn())); $this->assertTrue($ldap->add($ou2)); $this->assertTrue($ldap->dnExists($ou2->dn())); /* * search and test each method */ $search = $ldap->search(null, '(ou=Net_LDAP2*)'); $this->assertInstanceOf('Net_LDAP2_Search', $search); $this->assertEquals(2, $search->count()); // current() is supposed to return first valid element $e1 = $search->current(); $this->assertInstanceOf('Net_LDAP2_Entry', $e1); $this->assertEquals($e1->dn(), $search->key()); $this->assertTrue($search->valid()); // shift to next entry $search->next(); $e2 = $search->current(); $this->assertInstanceOf('Net_LDAP2_Entry', $e2); $this->assertEquals($e2->dn(), $search->key()); $this->assertTrue($search->valid()); // shift to non existent third entry $search->next(); $this->assertFalse($search->current()); $this->assertFalse($search->key()); $this->assertFalse($search->valid()); // rewind and test, // which should return the first entry a second time $search->rewind(); $e1_1 = $search->current(); $this->assertInstanceOf('Net_LDAP2_Entry', $e1_1); $this->assertEquals($e1_1->dn(), $search->key()); $this->assertTrue($search->valid()); $this->assertEquals($e1->dn(), $e1_1->dn()); // Dont rewind but call current, should return first entry again $e1_2 = $search->current(); $this->assertInstanceOf('Net_LDAP2_Entry', $e1_2); $this->assertEquals($e1_2->dn(), $search->key()); $this->assertTrue($search->valid()); $this->assertEquals($e1->dn(), $e1_2->dn()); // rewind again and test, // which should return the first entry a third time $search->rewind(); $e1_3 = $search->current(); $this->assertInstanceOf('Net_LDAP2_Entry', $e1_3); $this->assertEquals($e1_3->dn(), $search->key()); $this->assertTrue($search->valid()); $this->assertEquals($e1->dn(), $e1_3->dn()); /* * Try methods on empty search result */ $search = $ldap->search(null, '(ou=Net_LDAP2Test_NotExistentEntry)'); $this->assertInstanceOf('Net_LDAP2_Search', $search); $this->assertEquals(0, $search->count()); $this->assertFalse($search->current()); $this->assertFalse($search->key()); $this->assertFalse($search->valid()); $search->next(); $this->assertFalse($search->current()); $this->assertFalse($search->key()); $this->assertFalse($search->valid()); /* * search and simple iterate through the testentries. * then, rewind and do it again several times */ $search2 = $ldap->search(null, '(ou=Net_LDAP2*)'); $this->assertInstanceOf('Net_LDAP2_Search', $search2); $this->assertEquals(2, $search2->count()); for ($i = 0; $i <= 5; $i++) { $counter = 0; foreach ($search2 as $dn => $entry) { $counter++; // check on type $this->assertInstanceOf('Net_LDAP2_Entry', $entry); // check on key $this->assertThat(strlen($dn), $this->greaterThan(1)); $this->assertEquals($dn, $entry->dn()); } $this->assertEquals($search2->count(), $counter, "Failed at loop {$i}"); // revert to start $search2->rewind(); } /* * Cleanup */ $this->assertTrue($ldap->delete($ou1), 'Cleanup failed, please delete manually'); $this->assertTrue($ldap->delete($ou2), 'Cleanup failed, please delete manually'); } }
/** * Tests if entry changes are correctly written */ public function testWrite_entryChanges() { $testentries = $this->testentries; $testentries[] = Net_LDAP2_Entry::createFresh('cn=foo,ou=example,dc=com', array('cn' => 'foo')); $testentries[] = Net_LDAP2_Entry::createFresh('cn=footest,ou=example,dc=com', array('cn' => 'foo')); $this->assertEquals(6, count($testentries), "Init error: Expected count of test entries wrong, check test datasetup!"); $testconf = $this->defaultConfig; $testconf['change'] = 1; //prepare some changes $testentries[0]->delete('attr1'); // del whole attr $testentries[0]->delete(array('attr2' => 'baz')); // del spec. value $testentries[0]->delete(array('attr4', 'attr3' => 'bar')); // del mixed // prepare some replaces and adds $testentries[2]->replace(array('attr1' => 'newvaluefor1')); $testentries[2]->replace(array('attr2' => array('newvalue1for2', 'newvalue2for2'))); $testentries[2]->replace(array('attr3' => '')); // will result in delete $testentries[2]->replace(array('newattr' => 'foo')); // will result in add // delete whole entry $testentries[3]->delete(); // rename and move $testentries[4]->dn('cn=Bar,ou=example,dc=com'); $testentries[5]->dn('cn=foobartest,ou=newexample,dc=com'); // make sure we correctly get changes back from the API foreach ($testentries as $te) { $this->assertGreaterThanOrEqual(2, count($te->getChanges()), 'Probable BUG in Net_LDAP2_Entry detected! Changed entries do not report those changes back! (entry: ' . $te->dn() . ')'); } // carry out write $ldif = new Net_LDAP2_LDIF($this->outfile, 'w', $testconf); $this->assertTrue(is_resource($ldif->handle())); $ldif->write_entry($testentries); $this->assertFalse((bool) $ldif->error(), 'Failed writing entry to ' . $this->outfile . ': ' . $ldif->error(true)); $this->assertGreaterThan(0, filesize($this->outfile), "File '" . $this->outfile . "' is empty but should have content!"); $ldif->done(); // compare results $expected = array_map('conv_lineend', file(dirname(__FILE__) . '/ldif_data/changes.ldif')); // strip 4 starting lines because of comments in the file header: array_shift($expected); array_shift($expected); array_shift($expected); array_shift($expected); $writtenFileContents = array_map('conv_lineend', file($this->outfile)); $this->assertEquals($expected, $writtenFileContents, "Written file does not equal expected contents (" . realpath($this->outfile) . ")"); }