🌌 SpectraShell

🌌 SpectraShell

Current path: home/a1642gum/public_html/wp-includes/



⬆️ Go up: public_html

📄 Viewing: class-wp-block-metadata-registry.php

<?php
/**
 * Block Metadata Registry
 *
 * @package WordPress
 * @subpackage Blocks
 * @since 6.7.0
 */

/**
 * Class used for managing block metadata collections.
 *
 * The WP_Block_Metadata_Registry allows plugins to register metadata for large
 * collections of blocks (e.g., 50-100+) using a single PHP file. This approach
 * reduces the need to read and decode multiple `block.json` files, enhancing
 * performance through opcode caching.
 *
 * @since 6.7.0
 */
class WP_Block_Metadata_Registry {

	/**
	 * Container for storing block metadata collections.
	 *
	 * Each entry maps a base path to its corresponding metadata and callback.
	 *
	 * @since 6.7.0
	 * @var array<string, array<string, mixed>>
	 */
	private static $collections = array();

	/**
	 * Caches the last matched collection path for performance optimization.
	 *
	 * @since 6.7.0
	 * @var string|null
	 */
	private static $last_matched_collection = null;

	/**
	 * Stores the default allowed collection root paths.
	 *
	 * @since 6.7.2
	 * @var string[]|null
	 */
	private static $default_collection_roots = null;

	/**
	 * Registers a block metadata collection.
	 *
	 * This method allows registering a collection of block metadata from a single
	 * manifest file, improving performance for large sets of blocks.
	 *
	 * The manifest file should be a PHP file that returns an associative array, where
	 * the keys are the block identifiers (without their namespace) and the values are
	 * the corresponding block metadata arrays. The block identifiers must match the
	 * parent directory name for the respective `block.json` file.
	 *
	 * Example manifest file structure:
	 * ```
	 * return array(
	 *     'example-block' => array(
	 *         'title' => 'Example Block',
	 *         'category' => 'widgets',
	 *         'icon' => 'smiley',
	 *         // ... other block metadata
	 *     ),
	 *     'another-block' => array(
	 *         'title' => 'Another Block',
	 *         'category' => 'formatting',
	 *         'icon' => 'star-filled',
	 *         // ... other block metadata
	 *     ),
	 *     // ... more block metadata entries
	 * );
	 * ```
	 *
	 * @since 6.7.0
	 *
	 * @param string $path     The absolute base path for the collection ( e.g., WP_PLUGIN_DIR . '/my-plugin/blocks/' ).
	 * @param string $manifest The absolute path to the manifest file containing the metadata collection.
	 * @return bool True if the collection was registered successfully, false otherwise.
	 */
	public static function register_collection( $path, $manifest ) {
		$path = rtrim( wp_normalize_path( $path ), '/' );

		$collection_roots = self::get_default_collection_roots();

		/**
		 * Filters the root directory paths for block metadata collections.
		 *
		 * Any block metadata collection that is registered must not use any of these paths, or any parent directory
		 * path of them. Most commonly, block metadata collections should reside within one of these paths, though in
		 * some scenarios they may also reside in entirely different directories (e.g. in case of symlinked plugins).
		 *
		 * Example:
		 * * It is allowed to register a collection with path `WP_PLUGIN_DIR . '/my-plugin'`.
		 * * It is not allowed to register a collection with path `WP_PLUGIN_DIR`.
		 * * It is not allowed to register a collection with path `dirname( WP_PLUGIN_DIR )`.
		 *
		 * The default list encompasses the `wp-includes` directory, as well as the root directories for plugins,
		 * must-use plugins, and themes. This filter can be used to expand the list, e.g. to custom directories that
		 * contain symlinked plugins, so that these root directories cannot be used themselves for a block metadata
		 * collection either.
		 *
		 * @since 6.7.2
		 *
		 * @param string[] $collection_roots List of allowed metadata collection root paths.
		 */
		$collection_roots = apply_filters( 'wp_allowed_block_metadata_collection_roots', $collection_roots );

		$collection_roots = array_unique(
			array_map(
				static function ( $allowed_root ) {
					return rtrim( wp_normalize_path( $allowed_root ), '/' );
				},
				$collection_roots
			)
		);

		// Check if the path is valid:
		if ( ! self::is_valid_collection_path( $path, $collection_roots ) ) {
			_doing_it_wrong(
				__METHOD__,
				sprintf(
					/* translators: %s: list of allowed collection roots */
					__( 'Block metadata collections cannot be registered as one of the following directories or their parent directories: %s' ),
					esc_html( implode( wp_get_list_item_separator(), $collection_roots ) )
				),
				'6.7.2'
			);
			return false;
		}

		if ( ! file_exists( $manifest ) ) {
			_doing_it_wrong(
				__METHOD__,
				__( 'The specified manifest file does not exist.' ),
				'6.7.0'
			);
			return false;
		}

		self::$collections[ $path ] = array(
			'manifest' => $manifest,
			'metadata' => null,
		);

		return true;
	}

	/**
	 * Retrieves block metadata for a given block within a specific collection.
	 *
	 * This method uses the registered collections to efficiently lookup
	 * block metadata without reading individual `block.json` files.
	 *
	 * @since 6.7.0
	 *
	 * @param string $file_or_folder The path to the file or folder containing the block.
	 * @return array|null The block metadata for the block, or null if not found.
	 */
	public static function get_metadata( $file_or_folder ) {
		$file_or_folder = wp_normalize_path( $file_or_folder );

		$path = self::find_collection_path( $file_or_folder );
		if ( ! $path ) {
			return null;
		}

		$collection = &self::$collections[ $path ];

		if ( null === $collection['metadata'] ) {
			// Load the manifest file if not already loaded
			$collection['metadata'] = require $collection['manifest'];
		}

		// Get the block name from the path.
		$block_name = self::default_identifier_callback( $file_or_folder );

		return isset( $collection['metadata'][ $block_name ] ) ? $collection['metadata'][ $block_name ] : null;
	}

	/**
	 * Gets the list of absolute paths to all block metadata files that are part of the given collection.
	 *
	 * For instance, if a block metadata collection is registered with path `WP_PLUGIN_DIR . '/my-plugin/blocks/'`,
	 * and the manifest file includes metadata for two blocks `'block-a'` and `'block-b'`, the result of this method
	 * will be an array containing:
	 * * `WP_PLUGIN_DIR . '/my-plugin/blocks/block-a/block.json'`
	 * * `WP_PLUGIN_DIR . '/my-plugin/blocks/block-b/block.json'`
	 *
	 * @since 6.8.0
	 *
	 * @param string $path The absolute base path for a previously registered collection.
	 * @return string[] List of block metadata file paths, or an empty array if the given `$path` is invalid.
	 */
	public static function get_collection_block_metadata_files( $path ) {
		$path = rtrim( wp_normalize_path( $path ), '/' );

		if ( ! isset( self::$collections[ $path ] ) ) {
			_doing_it_wrong(
				__METHOD__,
				__( 'No registered block metadata collection was found for the provided path.' ),
				'6.8.0'
			);
			return array();
		}

		$collection = &self::$collections[ $path ];

		if ( null === $collection['metadata'] ) {
			// Load the manifest file if not already loaded.
			$collection['metadata'] = require $collection['manifest'];
		}

		return array_map(
			// No normalization necessary since `$path` is already normalized and `$block_name` is just a folder name.
			static function ( $block_name ) use ( $path ) {
				return "{$path}/{$block_name}/block.json";
			},
			array_keys( $collection['metadata'] )
		);
	}

	/**
	 * Finds the collection path for a given file or folder.
	 *
	 * @since 6.7.0
	 *
	 * @param string $file_or_folder The normalized path to the file or folder.
	 * @return string|null The normalized collection path if found, or null if not found.
	 */
	private static function find_collection_path( $file_or_folder ) {
		if ( empty( $file_or_folder ) ) {
			return null;
		}

		// Check the last matched collection first, since block registration usually happens in batches per plugin or theme.
		$path = rtrim( $file_or_folder, '/' );
		if ( self::$last_matched_collection && str_starts_with( $path, self::$last_matched_collection ) ) {
			return self::$last_matched_collection;
		}

		$collection_paths = array_keys( self::$collections );
		foreach ( $collection_paths as $collection_path ) {
			if ( str_starts_with( $path, $collection_path ) ) {
				self::$last_matched_collection = $collection_path;
				return $collection_path;
			}
		}
		return null;
	}

	/**
	 * Checks if metadata exists for a given block name in a specific collection.
	 *
	 * @since 6.7.0
	 *
	 * @param string $file_or_folder The path to the file or folder containing the block metadata.
	 * @return bool True if metadata exists for the block, false otherwise.
	 */
	public static function has_metadata( $file_or_folder ) {
		return null !== self::get_metadata( $file_or_folder );
	}

	/**
	 * Default identifier function to determine the block identifier from a given path.
	 *
	 * This function extracts the block identifier from the path:
	 * - For 'block.json' files, it uses the parent directory name.
	 * - For directories, it uses the directory name itself.
	 * - For empty paths, it returns an empty string.
	 *
	 * For example:
	 * - Path: '/wp-content/plugins/my-plugin/blocks/example/block.json'
	 *   Identifier: 'example'
	 * - Path: '/wp-content/plugins/my-plugin/blocks/another-block'
	 *   Identifier: 'another-block'
	 *
	 * This default behavior matches the standard WordPress block structure.
	 *
	 * @since 6.7.0
	 *
	 * @param string $path The normalized file or folder path to determine the block identifier from.
	 * @return string The block identifier, or an empty string if the path is empty.
	 */
	private static function default_identifier_callback( $path ) {
		// Ensure $path is not empty to prevent unexpected behavior.
		if ( empty( $path ) ) {
			return '';
		}

		if ( str_ends_with( $path, 'block.json' ) ) {
			// Return the parent directory name if it's a block.json file.
			return basename( dirname( $path ) );
		}

		// Otherwise, assume it's a directory and return its name.
		return basename( $path );
	}

	/**
	 * Checks whether the given block metadata collection path is valid against the list of collection roots.
	 *
	 * @since 6.7.2
	 *
	 * @param string   $path             Normalized block metadata collection path, without trailing slash.
	 * @param string[] $collection_roots List of normalized collection root paths, without trailing slashes.
	 * @return bool True if the path is allowed, false otherwise.
	 */
	private static function is_valid_collection_path( $path, $collection_roots ) {
		foreach ( $collection_roots as $allowed_root ) {
			// If the path matches any root exactly, it is invalid.
			if ( $allowed_root === $path ) {
				return false;
			}

			// If the path is a parent path of any of the roots, it is invalid.
			if ( str_starts_with( $allowed_root, $path ) ) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Gets the default collection root directory paths.
	 *
	 * @since 6.7.2
	 *
	 * @return string[] List of directory paths within which metadata collections are allowed.
	 */
	private static function get_default_collection_roots() {
		if ( isset( self::$default_collection_roots ) ) {
			return self::$default_collection_roots;
		}

		$collection_roots = array(
			wp_normalize_path( ABSPATH . WPINC ),
			wp_normalize_path( WP_CONTENT_DIR ),
			wp_normalize_path( WPMU_PLUGIN_DIR ),
			wp_normalize_path( WP_PLUGIN_DIR ),
		);

		$theme_roots = get_theme_roots();
		if ( ! is_array( $theme_roots ) ) {
			$theme_roots = array( $theme_roots );
		}
		foreach ( $theme_roots as $theme_root ) {
			$collection_roots[] = trailingslashit( wp_normalize_path( WP_CONTENT_DIR ) ) . ltrim( wp_normalize_path( $theme_root ), '/' );
		}

		self::$default_collection_roots = array_unique( $collection_roots );
		return self::$default_collection_roots;
	}
}



📁

Why Autism Will Never Interfere with Our Happiness

Here we are with another inspiring story about how a family beat the odds (and stereotype) of autism and emerged victorious. Through this series of Autism Success Stories, we want to celebrate the developments and achievements of our young stars and their families, and through them, want to let you know that there is always hope and support for you (as a parent and a professional).

 

This month, we feature 20-year-old Vishal Srinivas, and his parents – Viji and Srinivas. Srinivas works for a multinational corporation and Viji has been a teacher at SAI for 7 years. Vishal was a student at SAI for the duration too. Here is Viji sharing her’s and Vishal’s remarkable story of improvement and happiness.

 

On September 5th, 2000, I took Vishal for his first session with a Speech Language Pathologist (SLP) at Anushakti Nagar, Chembur. As soon as we stepped out of the building after the session, Vishal freed himself from my hold and took off like a bullet. He kept running (on the footpath, thankfully) and didn’t turn back even once. It was a new place and I was terrified. While chasing him, I kept thinking, “God, where am I? What is happening? How will I get through this?”

 

Fast forward to September 5th, 2015, and Vishal stepped out of home with his father to go to the bank. We have a ritual: whenever a person leaves from home, someone from the family stands in the balcony and waves. If I leave, my mother-in-law stands in the balcony. That day, Vishal took his long, self-assured strides (he’s 6’ 2”), stopped, turned around to look at the balcony and waved “Bye ma! Bye patima (grandma)!” It’s a norm for him to wave out to us in the balcony now. Then he takes his long strides, reaches the end of the road and waits for the person accompanying him to catch up – whether his dad or me. My son has come such a long way.

 

Vishal was initially admitted to Sevadaan Special School in Chembur. He was placed in the group of most heavily affected children (probably because the staff found it hard to handle children with autism). I was in awe of children there who were adept at cooking and were paid for it. Today, my son, the masterchef, strides into our kitchen like a lion strides into his territory and takes charge. He inspects what is being cooked, stirs simmering dishes and is keen on helping. It’s like he’s the supervisor and I’m the assistant. Not without good reason. He is immensely fond of cooking – in fact, it’s his passion. The other day, he was preparing his favorite potato sabzi and it turned out spicy. I told him so. Rather than getting anxious, he calmly added more tomatoes to reduce the spiciness. He has remarkable acumen when it comes to altering the taste of dishes, whether they have to be sweetened or spiced up. And when I tell him to turn off the gas or add salt to a dish, I am confident that he will do it. No need for me to double check. All this from a boy who could not sit in one place due to hyperactivity.

How my son conquered autism

Vishal is sensitive to sound. When he was about 8 years old, he would bang his head hard against my arm whenever he heard a loud honk. It would hurt. But with time, he has learned to put his long fingers into his ears and partly insulate himself against loud noises. I laugh to myself when teenagers passing by wonder aloud which device to talk to someone or listen to music is so small that it is not visible… During the initial years, I simply took him along (more out of compulsion) and hoped that he would take care of himself in public. But after I joined the family consultation program, I started giving him responsibilities during our monthly provision shopping. And he loved it. Now I tell him what he has to buy orally (he’s an auditory learner) and simply have to linger around. He thinks and buys what he has been entrusted with. And once we check out, bags containing the items he has bought are his responsibility.

 

It’s age appropriate too. How many neuro-typical 20-year-olds help their parents? In fact, parents have to be more careful with 20-year-olds today. Who are they hanging out with? Are they doing something wrong? Are they lying? Not with Vishal, or any other child with autism, I believe. Living with someone with autism is a totally different experience. Our kids are loving, helpful and honest. If Vishal opens the fridge and eats a chocolate (which he rarely does, because he knows he has to follow a strict diet), he promptly walks up to me and says “I ate a chocolate.” My son’s honesty and love are reassuring.

 

Living with someone with autism can be both frustrating and gratifying. Vishal’s OCD can cause both these emotions in me. Frustration, well, if you know someone with OCD, you know what I mean. Gratifying, because once he returns home from somewhere, he puts his footwear in place, changes his clothes, washes his hands and feet and only then gets on the bed. His and my awareness and understanding have increased each day after I joined the family consultation program. I have stopped giving instructions to Vishal – it has been two years now – and the relation between him and me has blossomed. I have gained immense confidence in understanding my child, and this has helped me address and reduce one of his biggest challenges – his anxiety.

 

I want to share an incident with you. Vishal’s anxiety had reached disturbing levels in 2010. He would indulge in self-injurious behavior often. Years of purely following instructions can do that to you. He would use self-injurious behavior as a means of communication whenever he was anxious, not just on himself, but on others too. He would pull or push anyone close by, and this was impeding all his progress. It made many people around him anxious too (including yours truly). But a few weeks ago, something different occurred. We have a yoga instructor who comes home and helps Vishal do yoga for an hour (Vishal suffers from asthma. So though he loves the outdoors, he can’t spend much time there). During yoga, Vishal sweats profusely, like the cricketers we see on TV. During one session, he was tired and said something to the instructor. The instructor assumed that he had spoken in Tamil and said “Say it in English.” That was where Vishal had a bout of anxiety. Two years ago, at such times, he would have started hitting himself after saying “Adchiko” – a warning that he was about to cause harm. But today, he sat on the sofa and within a few seconds I was there. “What happened Vishal?”, I asked. The look on his face gave me the feeling that every parent yearns for. He looked at me through eyes with tears almost ready to roll out of them, as if saying “Thank God you are here! I am in so much trouble!” He told me what was troubling him and himself said “No adchiko.” Vishal feels reassured in my presence now. He knows that I am there for him and looks up to me. We share many beautiful moments together. These wonderful improvements in his life are not only because of his effort – they have come because I have worked hard on myself too. The family consultation program has taught me to stay calm when Vishal feels anxious. That gave me the confidence to take care of him which, in turn, gave him the reassurance that he could rely on me for anything. He and I trust each other implicitly now.

my son has conquered autism and does not let it come in his way of enjoying life

I could go on and on… about his love for music from Jagjit Singh to Honey Singh, about how he interacts with my relatives like a mature individual, how he likes to join conversations, how responsibly he conducted himself during the last rites of my grandmother, how he smiled when my relative’s 5-year-old daughter kept harrowing him to speak to her… and on and on… about how impressed people who interact with him are, how he thoroughly enjoyed himself sitting with folded legs on the floor and eating from a banana leaf during a family function. It’s wonderful to see the once hyperactive boy riddled with anxiety now conduct himself with such dignity in public, and become the master chef of my kitchen, and our lives.

 

I believe that we cannot expect professionals ‘cure our children’ magically. Whether a child with autism, or a neuro-typical one, we parents have to spend time with them and help them develop. Not just spend time, we have to encourage them to think for themselves, and treat them with dignity and respect – like grown-ups. This is the biggest lesson that I have learned from Mrs. Kamini Lakhani and my son. I have met many professionals who are also parents of children on the spectrum. But I have never seen anyone give as much respect and build a bond with the children like Mrs. Lakhani. Through our interactions which have spanned more than 7 years, I have learned to respect my son and treat him with dignity, and to expect others to do the same for Vishal and all other children on the autism spectrum.

 

Kamini Lakhani’s thoughts:

 

It is truly heartening to read this wonderful account about Vishal’s emergence. I am privileged to witness this emergence from close quarters.

 

In the past, I have watched the agonizing effects of his anxiety, on himself and others around him. Today, this self assured, competent young man, brings joy to my heart, as he strides through life. What I see today is a beautiful, meaningful relationship between mother and son. A relationship that is based on trust. Hats off to Viji’s hard work and diligence.

 

I look forward with hope, for Vishal to find his place in the sun.

 

If you are the parent or guardian of someone with autism or a learning disability, your family can achieve these remarkable results too. Our parent training program will offer you all the support and guidance that you need for these landmark improvements.

  •  
    1
    Share
  •  
  •  
  •  
  •  
  • 1
  •  

Kamini Lakhani

Kamini Lakhani is the founder and director of SAI Connections. She has been providing services in the field of autism for more than 25 years and is the authorized director of Professional Training for RDI in India and the Middle East. She is also the mother of a young adult with autism.

25 COMMENTS

Leave a Reply

Your email address will not be published. Required fields are marked *