/** * If any attributes that were requested to be ordered by are not explicitly in the attribute selection, add them. * * @param array $attributes * @param null|string $alias * @return array */ protected function mergeOrderByAttributes(array $attributes, $alias = null) { if (!$this->isWildCardSelection() && !empty($this->orderBy)) { $orderBy = $this->getAttributesForAlias(array_keys($this->orderBy), $alias); foreach ($orderBy as $attribute) { if (!in_array(MBString::strtolower($attribute), MBString::array_change_value_case($attributes))) { $attributes[] = $attribute; } } } return $attributes; }
/** * {@inheritdoc} */ public function fromLdap($value) { $ldapType = ['Unknown']; $value = MBString::array_change_value_case($value); foreach ($this->getOptions() as $type => $classes) { if (MBString::array_change_value_case($classes) == $value) { $ldapType = [$type]; break; } } return $ldapType; }
/** * Checks to make sure all required attributes are present. * * @param array $attributes */ protected function validateAttributesToLdap(array $attributes) { if (!$this->schema) { return; } $missing = []; foreach ($this->schema->getRequiredAttributes() as $attribute) { if (!array_key_exists(MBString::strtolower($attribute), MBString::array_change_key_case($attributes))) { $missing[] = $attribute; } } if (!empty($missing)) { throw new LogicException(sprintf('The following required attributes are missing: %s', implode(', ', $missing))); } }
/** * Get the value of an array key in a case-insensitive way. * * @param array $options * @param string $key */ protected function getArrayValue(array $options, $key) { return MBString::array_change_key_case($options)[MBString::strtolower($key)]; }
/** * Check for a specific object type in the schema and validate it. * * @param array $schema * @param string $objectType * @return array * @throws SchemaParserException */ protected function getObjectFromSchema(array $schema, $objectType) { $objectSchema = null; foreach ($schema['objects'] as $ldapObject) { if (array_key_exists('type', $ldapObject) && MBString::strtolower($ldapObject['type']) == MBString::strtolower($objectType)) { $objectSchema = $ldapObject; } } if (is_null($objectSchema)) { throw new SchemaParserException(sprintf('Cannot find object type "%s" in schema.', $objectType)); } return $objectSchema; }
/** * Check if the attribute value/meaning should be inverted. Provided as a convenience (ie. enabled) * * @return bool */ protected function shouldInvertValue() { return in_array(MBString::strtolower($this->getAttribute()), MBString::array_change_value_case($this->getOptions()['invert'])); }
/** * Set all the names mapped to a single attribute from LDAP. This helps account for multiple mappings used for * different purposes. * * @param array $newEntry * @param string $attribute * @param array|string $value * @return mixed */ protected function setMappedNames(array $newEntry, $attribute, $value) { // Get all names mapped to this LDAP attribute name... if (!$this->schema->hasNamesMappedToAttribute($attribute)) { return $newEntry; } $mappedNames = $this->schema->getNamesMappedToAttribute($attribute); foreach ($mappedNames as $mappedName) { // Any names specifically selected for should be in the result array... if ($this->selectedButNotPartOfEntry($mappedName, $newEntry)) { $newEntry[MBString::array_search_get_value($mappedName, $this->selectedAttributes)] = $value; } } return $newEntry; }
/** * Make sure that the current attribute has actually been defined. * * @throws AttributeConverterException */ protected function validateCurrentAttribute() { if (!array_key_exists(MBString::strtolower($this->getAttribute()), MBString::array_change_key_case($this->getOptions()))) { throw new AttributeConverterException(sprintf('Attribute "%s" must be defined in the converter options.', $this->getAttribute())); } }
/** * Determine how to get the value for the attribute from the LDAP entry being compared, and return that value. * * @param array|LdapObject $entry * @param string $attribute * @return mixed */ protected function getComparisonValue($entry, $attribute) { $alias = null; if (!empty($this->aliases)) { list($alias, $attribute) = LdapUtilities::getAliasAndAttribute($attribute); } $value = ''; if (is_array($entry) && isset($entry[$attribute])) { $value = $entry[$attribute]; // Be forgiving if they are hydrating to an array and the case of the attribute was not correct. } elseif (is_array($entry) && array_key_exists(MBString::strtolower($attribute), MBString::array_change_key_case($entry))) { $value = MBString::array_change_key_case($entry)[MBString::strtolower($attribute)]; // Only get the value if there is no alias requested, or if an alias was requested the object type must match the alias. } elseif ($entry instanceof LdapObject && (!$alias || $entry->isType($this->aliases[$alias]->getObjectType())) && $entry->has($attribute)) { $value = $entry->get($attribute); } // How to handle multi-valued attributes? This will at least prevent errors, but may not be accurate. $value = is_array($value) ? reset($value) : $value; return $this->convertValueToString($value); }
/** * Whether a specific attribute is defined as multivalued or not. * * @param string $attribute * @return bool */ public function isMultivaluedAttribute($attribute) { return in_array(MBString::strtolower($attribute), MBString::array_change_value_case($this->multivaluedAttributes)); }
/** * @param string $attribute * @return int */ protected function getBitForAttribute($attribute) { $bit = MBString::array_change_key_case($this->getOptions()['typeMap'])[MBString::strtolower($attribute)]; $bit = in_array($this->getAttribute(), $this->getOptions()['types']['type']) ? -1 * abs($bit) : $bit; return $bit; }
/** * @param GPOLink[] $values * @param GPOLink[] $toRemove * @return GPOLink[] */ protected function removeGPOLinksFromArray(array $values, array $toRemove) { foreach ($toRemove as $value) { $dn = $this->getGPOLinkDN($value); foreach ($values as $index => $originalValue) { if (MBString::strtolower($originalValue->getGpo()->get('dn')) == MBString::strtolower($dn)) { unset($values[$index]); break; } } } return $values; }
/** * Modifies the existing list of addresses to set the default for a specific address type. * * @param string $defaultAddress */ protected function modifyDefaultAddress($defaultAddress) { $values = is_array($this->getLastValue()) ? $this->getLastValue() : [$this->getLastValue()]; $addressType = $this->getArrayValue($this->getOptions()['addressType'], $this->getAttribute()); $isAddressInArray = in_array(MBString::strtolower($defaultAddress), MBString::array_change_value_case($values)); $length = strlen($addressType); foreach ($values as $index => $address) { // If another address is already the default then it must be changed. if (substr($address, 0, $length) === strtoupper($addressType) && $address !== $defaultAddress) { $values[$index] = substr_replace($address, $addressType, 0, $length); // If the address is the one we are looking for but is not the default, then make it the default. } elseif ($isAddressInArray && MBString::strtolower($address) == MBString::strtolower($defaultAddress)) { $values[$index] = $defaultAddress; } } // It was not already an address in the array, and the other default would have been changed now. if (!in_array($defaultAddress, $values)) { $values[] = $defaultAddress; } $this->setLastValue($values); }
/** * Takes all parameters (%username%, %someParameter%) within an attribute value and first checks for explicitly * set values for the parameter, then checks to see if the parameter name is a different attribute. If found it * takes the value either explicitly set or of the other attribute and replaces it within the original attribute. * * @param array $parameters All of the parameters found within the value. * @param array|string $original The original value for the attribute, containing the parameters. * @param array $attributes All of the attributes being sent to LDAP. * @return string The attribute value after the passed parameters have been set. */ protected function getValueForParameters(array $parameters, $original, array $attributes) { $wasArray = is_array($original); $original = $wasArray ? $original : [$original]; foreach (array_keys($original) as $index) { foreach ($parameters as $parameter) { $value = ''; // Explicitly set parameters values will take precedence if (array_key_exists(MBString::strtolower($parameter), MBString::array_change_key_case($this->parameters))) { $value = array_change_key_case($this->parameters)[MBString::strtolower($parameter)]; } elseif (array_key_exists(MBString::strtolower($parameter), MBString::array_change_key_case($attributes))) { $value = MBString::array_change_key_case($attributes)[MBString::strtolower($parameter)]; } if (is_array($value) && count($value) !== 1) { throw new InvalidArgumentException(sprintf('Cannot use a multi-valued attribute "%s" as a parameter.', $parameter)); } $value = is_array($value) && count($value) == 1 ? reset($value) : $value; $original[$index] = preg_replace("/" . self::PARAM_MARKER . $parameter . self::PARAM_MARKER . "/", $value, $original[$index]); } } return $wasArray ? $original : $original[0]; }
/** * This formats the orderBy array to ignore case differences between the orderBy name and the actually selected name, * such as for sorting arrays. * * @param $selected * @param $aliases * @return array */ protected function getFormattedOrderBy($selected, $aliases) { if (!empty($aliases) && !$this->isWildCardSelection()) { $orderBy = []; foreach ($this->orderBy as $attribute => $direction) { list($alias, $attr) = LdapUtilities::getAliasAndAttribute($attribute); $orderAttr = MBString::array_search_get_value($attr, $selected); $orderAttr = $alias ? "{$alias}.{$orderAttr}" : $orderAttr; $orderBy[$orderAttr] = $direction; } } else { $orderBy = $this->orderBy; } return $orderBy; }
/** * Given an array of attribute names, get all of the batches they have with their respective indexes * * @param array $attributes * @return array */ protected function getBatchesForAttributes(array $attributes) { $batches = []; foreach ($this->batches as $index => $batch) { /** @var Batch $batch */ if (in_array(MBString::strtolower($batch->getAttribute()), MBString::array_change_value_case($attributes))) { $batches[$index] = $batch; } } return $batches; }
/** * Given the TSPropertyArray binary data, extract out all of the TSProperty values. * * @param string $tsPropArray * @return array */ protected function decode($tsPropArray) { $tsPropArray = bin2hex($tsPropArray); // The signature is a 2-byte unicode character at the front $this->signature = MBString::chr(hexdec(substr($tsPropArray, 0, 2))); // The property count is a 2-byte unsigned integer indicating the number of elements for the tsPropertyArray // It starts at position 2. The actual variable data begins at position 4. $length = $this->addTSPropData(substr($tsPropArray, 4), hexdec(substr($tsPropArray, 2, 2))); // Reserved data length + (count and sig length == 4) + the added lengths of the TSPropertyArray // This saves anything after that variable TSPropertyArray data, so as to not squash anything stored there if (strlen($tsPropArray) > 4 + $length) { $this->postBinary = hex2bin(substr($tsPropArray, 4 + $length)); } }
/** * Performs the logic for switching the LDAP server connection. * * @param string|null $currentServer The server we are currently on. * @param string|null $wantedServer The server we want the connection to be on. * @param LdapOperationInterface $operation */ protected function switchServerIfNeeded($currentServer, $wantedServer, LdapOperationInterface $operation) { if ($operation instanceof AuthenticationOperation || MBString::strtolower($currentServer) == MBString::strtolower($wantedServer)) { return; } if ($this->connection->isBound()) { $this->connection->close(); } $this->connection->connect(null, null, false, $wantedServer); }
/** * @return bool */ protected function expectsBool() { return MBString::strtolower($this->getOptions()['bool']) == MBString::strtolower($this->getAttribute()); }
/** * Form the "name" string that the cache uses to refer to this item. * * @param string $itemType * @param string $itemName * @return string */ protected function getCacheName($itemType, $itemName) { return MBString::strtolower($this->cachePrefix . '/' . $itemType . '/' . $itemName); }
/** * Get the value of an attribute. An attribute with multiple values will return an array of values. * * @param string $attribute * @return mixed */ public function get($attribute) { if ($this->has($attribute)) { return MBString::array_change_key_case($this->attributes)[MBString::strtolower($attribute)]; } else { throw new InvalidArgumentException(sprintf('Attribute "%s" is not defined for this LDAP object.', $attribute)); } }