> */ private $nodes = array(); /** * Adds a node. A node whose `@id` is already in the graph is not added again. * * @since 1.0.0 * * @param array|null $node Node, or null for "nothing to add". * @return bool Whether the node was added. */ public function add( ?array $node ): bool { if ( null === $node || empty( $node['@id'] ) || ! is_string( $node['@id'] ) || isset( $this->nodes[ $node['@id'] ] ) ) { return false; } $clean = self::clean( $node ); if ( ! is_array( $clean ) || ! isset( $clean['@type'] ) ) { return false; } $this->nodes[ $node['@id'] ] = $clean; return true; } /** * Whether a node with this id is in the graph. * * @since 1.0.0 * * @param string $id The `@id`. * @return bool */ public function has( string $id ): bool { return isset( $this->nodes[ $id ] ); } /** * One node. * * @since 1.0.0 * * @param string $id The `@id`. * @return array|null */ public function get( string $id ): ?array { return $this->nodes[ $id ] ?? null; } /** * The nodes as a list. * * @since 1.0.0 * * @return array> */ public function nodes(): array { return array_values( $this->nodes ); } /** * Removes empty strings, nulls and empty lists, at every depth. Numbers, `0` and `false` stay. * * @since 1.0.0 * * @param mixed $value Any value. * @return mixed The cleaned value; null when nothing is left. */ public static function clean( $value ) { if ( is_array( $value ) ) { $out = array(); $is_list = array_keys( $value ) === range( 0, count( $value ) - 1 ); foreach ( $value as $key => $item ) { $item = self::clean( $item ); if ( null === $item ) { continue; } if ( $is_list ) { $out[] = $item; } else { $out[ $key ] = $item; } } return $out ? $out : null; } if ( null === $value || '' === $value ) { return null; } return $value; } }