acf-composer icon indicating copy to clipboard operation
acf-composer copied to clipboard

enhancment: Add the possibility to set the parent class in children options page

Open Androlax2 opened this issue 4 years ago • 5 comments

You can now have for Example

Structure Options page like that :

  • Top
    • Children 1

Children 1 class can have :

public $parent = Top::class;

Androlax2 avatar Sep 15 '20 10:09 Androlax2

excellent.

can you make the conditional check the class type? https://github.com/Log1x/acf-composer/blob/master/src/Concerns/InteractsWithPartial.php#L20-L23 is an example

Log1x avatar Sep 15 '20 10:09 Log1x

excellent.

can you make the conditional check the class type? https://github.com/Log1x/acf-composer/blob/master/src/Concerns/InteractsWithPartial.php#L20-L23 is an example

Done, I guess

Androlax2 avatar Sep 15 '20 10:09 Androlax2

Also, be careful, when adding options page, if the parent have not been initialized first, childrens won't work. Didn't found where you initialize everything. In my custom wordpress theme I do that (Not the best thing I guess, but it works) :

$options = "App\\Acf\\Options";

$optionsPages = new \Illuminate\Support\Collection();

foreach (glob(dirname(__FILE__) . '/App/Acf/Options/*.php') as $filePath) {
	require_once $filePath;

	$class = basename($filePath, '.php');

	if (class_exists("$options\\$class")) {
		$class = "$options\\$class";
		$obj = new $class();
		if ($obj->parent) {
			if (!class_exists($obj->parent)) throw new \InvalidArgumentException("The parent class {$obj->parent} does not exist.");
			$objParent = new $obj->parent();
			if (!$optionsPages->contains($objParent)) $optionsPages->push($objParent);
		}
		$obj = new $obj();
		if (!$optionsPages->contains($obj)) $optionsPages->push($obj);
	}
}
$optionsPages->map(
	function ($optionPage) {
		$optionPage->compose();
	}
);

Androlax2 avatar Sep 15 '20 11:09 Androlax2

I ran into the same problem. Tried the fix above and it didn't work anymore.

However I found another solution that works in the meantime. If you add an options page like you normally would (anywhere in your theme).

add_action('after_setup_theme', function () {
  acf_add_options_page([
    'page_title'  => 'Settings',
    'menu_title'  => 'Settings',
    'menu_slug'  => 'site_settings',
    'redirect'  => false,
  ]);
});

You can then use $parent = 'site_settings' attribute on the options. Parent attribute breaks when the options page does not exists first.

slackday avatar Jul 05 '21 13:07 slackday

I may found a solution.

My custom Wordpress Theme has evolved since.

I have an ACFLoader Class that have this method in :

    /**
     * Load ACF Options
     *
     * @param string $namespace
     * @param string $path
     *
     * @throws InvalidArgumentException
     */
    private static function loadOptions(string $namespace, string $path): void
    {
        $optionsPages = new Collection();

        foreach (self::recursiveGlob("$path/*.php") as $acfOptionFieldPath) {
            include_once $acfOptionFieldPath;

            $class = basename($acfOptionFieldPath, '.php');

            if (!class_exists("$namespace\\$class")) {
                continue;
            }

            $class = "$namespace\\$class";
            $option = new $class();

            if ($option->parent) {
                if (!class_exists($option->parent)) {
                    throw new InvalidArgumentException("The parent class {$option->parent} does not exist.");
                }

                $optionParent = new $option->parent();

                if (!$optionsPages->contains($optionParent)) {
                    $optionsPages->push($optionParent);
                }
            }

            $option = new $option();

            if ($optionsPages->contains($option)) {
                continue;
            }

            $optionsPages->push($option);
        }// end foreach

        $optionsPages->map(static fn ($optionPage) => $optionPage->compose());
    }

It basically run through all options pages and then push the option page to an array $optionsPages.

If there is a parent, it create a new option page and push it to the array. So we always have the parent option page existing when the "children" option page is requesting it

Androlax2 avatar Jul 05 '21 14:07 Androlax2

Fixed in #193

Log1x avatar Feb 26 '24 19:02 Log1x