Powers not compiled and not implemented in class header #997

Closed
opened 2023-05-15 11:37:08 +00:00 by SimonvanDoorne · 11 comments
Member

Steps to reproduce the issue

  1. Create any component + admin view.
  2. select power to be compiled
    image

Expected result

3 problems occur:
Problem 1: Power is not even compiled:
image
Problem 2: Use is not implemented in the controller
image
Problem 3: even when you manually create the class and add it to the use list, its not actually loaded
image

Manually loading it using require_once does load the file:
image

Actual result

System information (as much as possible)

  • OS Name & Version: Windows 10 pro
  • MySql Version:
  • Apache Version:
  • PHP Version: 7.4
  • Joomla Version: 3.10.11
  • JCB Version: 3.1.24
  • Browser: Google Chrome

Additional comments

I have asked multiple other programmers about the class not loading when it is defined in the use lines, and nobody managed to figure it out. It should just autoload but it just doesn't.

### Steps to reproduce the issue 1) Create any component + admin view. 2) select power to be compiled ![image](/attachments/f20efa88-9dee-41f2-9046-0d5b53cae602) ### Expected result 3 problems occur: **Problem 1: Power is not even compiled:** ![image](/attachments/30b0e767-0925-4661-b69f-25de87c6227f) **Problem 2: Use is not implemented in the controller** ![image](/attachments/c49c83fb-fd67-4844-888b-daa413c40eed) **Problem 3: even when you manually create the class and add it to the use list, its not actually loaded** ![image](/attachments/d7bdcd56-6c33-41b6-8ada-d885bcdca372) Manually loading it using require_once does load the file: ![image](/attachments/32648374-8c17-4b82-bc06-a7880a358123) ### Actual result ### System information (as much as possible) - OS Name & Version: Windows 10 pro - MySql Version: - Apache Version: - PHP Version: 7.4 - Joomla Version: 3.10.11 - JCB Version: 3.1.24 - Browser: Google Chrome ### Additional comments I have asked multiple other programmers about the class not loading when it is defined in the use lines, and nobody managed to figure it out. It should just autoload but it just doesn't.
Owner

Okay chrome browser is a no go, it is to much involved with the local system. Please use Firefox.

Then please make sure you have the plugin enabled:
image

And you have the plugin linked:
image

Their is another way to no link powers, and I am planing to push out some tutorials surrounding that soon. But in short you need to use the SPK value, in place of the class name in your code once.
image

Like this:

// as class
$class = new Super___ccf3141a_929d_4466_b122_9ace2eea8d70___Power();
// as abstract class
Super___ccf3141a_929d_4466_b122_9ace2eea8d70___Power::get($id);

This will auto load powers from V3.1.24

But the old way of direct linking should still work, and is still my main mode of using powers as it is faster, and more stable.

I see you have it set to Based on Component so is the component set to load powers? and what happens if you change it to Always.

I tested this:
image

Saved and compiled, and the result was:
image

What that tells me, if all your settings in JCB is correct, and your in the right browser and it still fails, then there is a system issue.

Having said that, I don't mean to imply that I am unwilling to fix it. Rather, I simply can't without more details, as I need to be able to replicate the issue. In the industry, we attempt to unify the environment by using a container.

Utilizing a container ensures that we all operate in the same environment. This is why I built Octojoom. In this way, we are all in the same environment, enabling us to debug and observe the same phenomena most effectively.

Given that we are only two core developers on JCB at this time, targeting more diverse environments is currently unfeasible. Therefore, to ensure that your PHP setup matches ours, check the docker file, and observe all the steps it takes in preparing the container. You will see here all the modules and other necessary components that must be installed to guarantee we have the same environment. The Joomla docker container is intended to be the optimal way to run Joomla, and so JCB is simply following that as a baseline.

However, I am not suggesting that there is no way to get JCB to run in other environments. I am merely stating that I can't be the one to make it happen. I transitioned entirely to Ubuntu in 2010 (I believe), and I have never looked back. As a programmer, I can confidently say that I have found my home. If I were a desktop developer, this would not be ideal, as most people use Windows.

But since I am a cloud developer, the landscape is quite different. The server market is heavily dominated by Linux, with a significant majority of cloud systems running on Linux-based operating systems. While the exact figure varies, it's safe to say that between 89% and 98% of all cloud systems are Linux-based, reflecting the robustness, security, and flexibility of Linux in handling server tasks. This means I am now operating in the environment of my end product. For this reason, I don't see the wisdom in reverting to Windows.

Okay chrome browser is a no go, it is to much involved with the local system. Please use Firefox. Then please make sure you have the plugin enabled: ![image](/attachments/13ec529d-123f-4941-bfb7-6817a7666905) And you have the plugin linked: ![image](/attachments/be4b4b18-e9af-40e8-931c-c5ba895dce79) Their is another way to no link powers, and I am planing to push out some tutorials surrounding that soon. But in short you need to use the SPK value, in place of the class name in your code once. ![image](/attachments/2b2777ec-0673-4660-8243-c2e991a01e30) Like this: ``` // as class $class = new Super___ccf3141a_929d_4466_b122_9ace2eea8d70___Power(); // as abstract class Super___ccf3141a_929d_4466_b122_9ace2eea8d70___Power::get($id); ``` This will auto load powers from V3.1.24 But the old way of direct linking should still work, and is still my main mode of using powers as it is faster, and more stable. I see you have it set to `Based on Component` so is the component set to load powers? and what happens if you change it to `Always`. I tested this: ![image](/attachments/05ab0f99-e5bb-4ba1-aa76-28733842cefd) Saved and compiled, and the result was: ![image](/attachments/9d7402e8-6cf7-48c8-9327-a62c8c050b84) What that tells me, if all your settings in JCB is correct, and your in the right browser and it still fails, then there is a system issue. Having said that, I don't mean to imply that I am unwilling to fix it. Rather, I simply can't without more details, as I need to be able to replicate the issue. In the industry, we attempt to unify the environment by using a container. Utilizing a container ensures that we all operate in the same environment. This is why I built [Octojoom](https://git.vdm.dev/octoleo/octojoom). In this way, we are all in the same environment, enabling us to debug and observe the same phenomena most effectively. Given that we are only two core developers on JCB at this time, targeting more diverse environments is currently unfeasible. Therefore, to ensure that your PHP setup matches ours, check the [docker file](https://github.com/joomla-docker/docker-joomla/blob/master/3.10/php8.0/apache/Dockerfile), and observe all the steps it takes in preparing the container. You will see [here](https://github.com/joomla-docker/docker-joomla/blob/master/3.10/php8.0/apache/Dockerfile#L22) all the modules and other necessary components that must be installed to guarantee we have the same environment. The Joomla docker container is intended to be the optimal way to run Joomla, and so JCB is simply following that as a baseline. However, I am not suggesting that there is no way to get JCB to run in other environments. I am merely stating that I can't be the one to make it happen. I transitioned entirely to Ubuntu in 2010 (I believe), and I have never looked back. As a programmer, I can confidently say that I have found my home. If I were a desktop developer, this would not be ideal, as most people use Windows. But since I am a cloud developer, the landscape is quite different. The server market is heavily dominated by Linux, with a significant majority of cloud systems running on Linux-based operating systems. While the exact figure varies, it's safe to say that between 89% and 98% of all cloud systems are Linux-based, reflecting the robustness, security, and flexibility of Linux in handling server tasks. This means I am now operating in the environment of my end product. For this reason, I don't see the wisdom in reverting to Windows.
Owner

You mentioned that you've consulted other programmers. I would encourage you to invite them to participate in this discussion as well. Why should any conversation about issues in the JCB core be held privately?

We need more developers actively contributing to JCB.

This includes responding to issues, testing beta version releases, participating in discussions, and essentially sharing their perspectives. If more than one programmer is experiencing this issue, they should all comment on this issue with their findings and screenshots. This collective input will help me resolve the issue more quickly. A community is not comprised of two core developers and the rest as users; rather, it means that everyone is a contributor.

You mentioned that you've consulted other programmers. I would encourage you to invite them to participate in this discussion as well. Why should any conversation about issues in the JCB core be held privately? We need more developers actively contributing to JCB. This includes responding to issues, testing beta version releases, participating in discussions, and essentially sharing their perspectives. If more than one programmer is experiencing this issue, they should all comment on this issue with their findings and screenshots. This collective input will help me resolve the issue more quickly. A community is not comprised of two core developers and the rest as users; rather, it means that everyone is a contributor.
Author
Member

Thanks for the quick response! I checked:

  • One plugins was not activated, and now the use class is properly added! problem 1 & 2 fixed!

  • All compiling is done in Firefox
    Sorry for the incoming image spam btw, i find it easier to explain with images than just text

Now i have found something i don't understand:
Attempting to use the class in the postSaveHook works great
image
image

But when i attempt the same thing in the custom buttons area
image
The button shows up but the class is not loaded
image

Dumping the get_loaded_classes() function shows that when the postSaveHook is called, 437 classes are loaded while in the controller 'only' 365 are. When dumping get_loaded_classes() in the postsavehook shows that these classes are loaded
image
While if you dump get_loaded_classes() in the controller function it is missing all these classes. Could this be a hint to where this goes wrong?

Thanks for the quick response! I checked: - [x] One plugins was not activated, and now the use class is properly added! problem 1 & 2 fixed! - [x] All compiling is done in Firefox Sorry for the incoming image spam btw, i find it easier to explain with images than just text Now i have found something i don't understand: Attempting to use the class in the postSaveHook works great ![image](/attachments/70897f0a-ea4d-42ec-becd-8c84b8d310ff) ![image](/attachments/3ea7d857-3122-496a-8f89-0320e3be51d8) But when i attempt the same thing in the custom buttons area ![image](/attachments/e787ec3e-07a0-48b4-b8ad-cee1f3a08af7) The button shows up but the class is not loaded ![image](/attachments/9872e99d-b368-4e41-85d8-80c955714c46) Dumping the get_loaded_classes() function shows that when the postSaveHook is called, 437 classes are loaded while in the controller 'only' 365 are. When dumping get_loaded_classes() in the postsavehook shows that these classes are loaded ![image](/attachments/6c8be4da-ca16-44c2-86cb-e18ef7cfbfa1) While if you dump get_loaded_classes() in the controller function it is missing all these classes. Could this be a hint to where this goes wrong?
Author
Member

I accidentally closed it, sorry about that. If you want me to show this issue you can always shoot me a message on telegram

I accidentally closed it, sorry about that. If you want me to show this issue you can always shoot me a message on telegram
Owner

Hmm I am not sure I follow all your saying... so in reflection this is what I understood. Your adding the class via the Class Headers tab, and this works now.

Then using this class in the custom code works if your using the postSaveHook method, but not if you directly add a new function to the controller, via the Custom Buttons tab.

So this is where you lose me... if the Class is loaded to the head of the controller file via the Class Headers tab, it means the class is loaded to the powers area, and linked via the use statement at the top of the file.

This means no matter where your trying to use the class in the file it should work, unless its no longer loaded to the head of the file, in which case that is the issue, and no the where the class is used.

Hmm I am not sure I follow all your saying... so in reflection this is what I understood. Your adding the class via the **Class Headers** tab, and this works now. Then using this class in the custom code works if your using the `postSaveHook` method, but not if you directly add a new function to the controller, via the **Custom Buttons** tab. So this is where you lose me... if the Class is loaded to the head of the controller file via the **Class Headers** tab, it means the class is loaded to the powers area, and linked via the `use` statement at the top of the file. This means no matter where your trying to use the class in the file it should work, unless its no longer loaded to the head of the file, in which case that is the issue, and no the where the class is used.
Owner

Remember there are two controllers per view, the controller for the list view and the controller for the edit view. Make sure that your targeting the correct file in all instances.

Remember there are two controllers per view, the controller for the list view and the controller for the edit view. Make sure that your targeting the correct file in all instances.
Owner

By the way the postSaveHook is found in the edit view controller, and the first controller block in the Custom Buttons tab, is targeting the edit view controller.

By the way you don not need to actually add a button to add methods into these areas. Just adding code will still work.

So I tested what I understood, and it works:

Add the power:
image

Use the power:
image

	public function syncPowers()
	{
		// Check for request forgeries
		JSession::checkToken() or die(JText::_('JINVALID_TOKEN'));

		// get IDS of the selected powers
		$item = $this->input->post->get('jform', array(), 'array');

		// check if there is any selections
		if (empty($item['id']))
		{
			// just to test
			$our_string = 'has some value';
			if (StringHelper::check($our_string))
			{
				echo '<pre>'; var_dump($our_string); echo '</pre>'; exit;
			}
		}
	}

And this works perfectly.... but again if targeted by a list view button, we must use the controllers (list view) area, and if by an edit view me must use the first controller for the edit view.

By the way the `postSaveHook` is found in the edit view controller, and the first controller block in the **Custom Buttons** tab, is targeting the edit view controller. By the way you don not need to actually add a button to add methods into these areas. Just adding code will still work. So I tested what I understood, and it works: Add the power: ![image](/attachments/a5df93e1-ccf4-4e8c-9443-4d82ab124688) Use the power: ![image](/attachments/631ba1b5-81a2-4351-981f-5bf3a7a2c42a) ``` public function syncPowers() { // Check for request forgeries JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); // get IDS of the selected powers $item = $this->input->post->get('jform', array(), 'array'); // check if there is any selections if (empty($item['id'])) { // just to test $our_string = 'has some value'; if (StringHelper::check($our_string)) { echo '<pre>'; var_dump($our_string); echo '</pre>'; exit; } } } ``` And this works perfectly.... but again if targeted by a list view button, we must use the controllers (list view) area, and if by an edit view me must use the first controller for the edit view.
Author
Member

Just to test i have added my headertest class to all options in the 'class headers' tab.
Next i tried all combinations of the target (single/both/list) and the type (default/selection/function) in the custom buttons to see if that changed something, sadly it didn't. I went looking some more into why there are more classes loaded when the postSaveHook is triggered and found something that might explain it.
image
The spl_autoload_register that registers the component namespace is loaded in the DemoHelper class, which is not loaded when you're calling the test function in the controller.

It is possible to just add random strings in the use list at the start of the file for example:
image
This throws no error. so only adding the use to the list is not enough for it to actually attempt to load the namespaces. Copy pasting the autoloader from the DemoHelper into the controller loads the Headertest class without issue. My conclusion (and please correct me if i'm wrong here):
The class DemoControllerLook extends the FormController circumventing the loading of the DemoHelper class. Since the FormController is a extension of the BaseController the actual component (and thus the component namespace) is not loaded.

Again i could be completely wrong here, i still don't know why you can just add a bunch of nonsense use lines and no errors occur.

Just to test i have added my headertest class to all options in the 'class headers' tab. Next i tried all combinations of the target (single/both/list) and the type (default/selection/function) in the custom buttons to see if that changed something, sadly it didn't. I went looking some more into why there are more classes loaded when the `postSaveHook` is triggered and found something that might explain it. ![image](/attachments/e46af850-c4ed-46cc-bb15-c1fbd7580194) The spl_autoload_register that registers the component namespace is loaded in the `DemoHelper` class, which is not loaded when you're calling the test function in the controller. It is possible to just add random strings in the use list at the start of the file for example: ![image](/attachments/6a432cee-2cf7-45f3-be4d-06c7edaa4fc2) This throws no error. so only adding the use to the list is not enough for it to actually attempt to load the namespaces. Copy pasting the autoloader from the DemoHelper into the controller loads the Headertest class without issue. My conclusion (and please correct me if i'm wrong here): The class `DemoControllerLook` extends the `FormController` circumventing the loading of the `DemoHelper` class. Since the `FormController` is a extension of the `BaseController` the actual component (and thus the component namespace) is not loaded. Again i could be completely wrong here, i still don't know why you can just add a bunch of nonsense `use` lines and no errors occur.
Owner

Okay I am not sure what your trying to do... but what ever it is, you lost me.

Simple truth is that the helper class loads with every component call that looks like this ?option=com_componentname since this triggers the entry point file that always loads the helper class.

That said if your trying to trigger your component from another component you will need to use the Power (Load by plugin) approach.

I don't think I can help you any further... as JCB is not the issue here. JCB does what it should do.

Obviously adding nonsense stuff will break things.

Okay I am not sure what your trying to do... but what ever it is, you lost me. Simple truth is that the helper class loads with every component call that looks like this `?option=com_componentname` since this triggers the entry point file that always loads the helper class. That said if your trying to trigger your component from another component you will need to use the Power (Load by plugin) approach. I don't think I can help you any further... as JCB is not the issue here. JCB does what it should do. Obviously adding nonsense stuff will break things.
Author
Member

As a second test i went into the JCB admin views controller and put a dump of get_declared_classes() in the runExpansion function called from the run expansion button in the admin_views view. and compared it between that and the dump of the get_declared_classes() of the demo list view controller. Turns out that the JCB ComponentbuilderControllerAdmin_views controller loads 4 extra classes compared to the DemoControllerLooks. One of those 4 extra classes is the ComponentbuilderHelper class. Exactly the class that has the autoload for the namespace. I am starting to having trouble wrapping my head around how this all works but from what i'm getting the general helper file jcb generates is not loaded everywhere in the components it builds.

As a second test i went into the JCB admin views controller and put a dump of get_declared_classes() in the `runExpansion` function called from the run expansion button in the admin_views view. and compared it between that and the dump of the get_declared_classes() of the demo list view controller. Turns out that the JCB `ComponentbuilderControllerAdmin_views` controller loads 4 extra classes compared to the `DemoControllerLooks`. One of those 4 extra classes is the `ComponentbuilderHelper` class. Exactly the class that has the autoload for the namespace. I am starting to having trouble wrapping my head around how this all works but from what i'm getting the general helper file jcb generates is not loaded everywhere in the components it builds.
Owner

I have no idea what your doing... since none of it makes sense. I have never needed to any of this, and all my extensions work.

You have not confirmed your system has all the needed PHP modules set... I really do not understand what your saying.

I load hundreds of classes all over the system and do not have any of these issues you speak about... not that I actually understand what your saying.

The only conclusion I have is that your not matching this correctly and that is it.

I have demonstrated that this feature is stable and works as expected. Maybe its time for you to make a detailed video of what your doing... from beginning to end, not skipping any part. Without fully understanding what your really doing I am wasting my time.

I have no idea what your doing... since none of it makes sense. I have never needed to any of this, and all my extensions work. You have not confirmed your system has all the needed PHP modules set... I really do not understand what your saying. I load hundreds of classes all over the system and do not have any of these issues you speak about... not that I actually understand what your saying. The only conclusion I have is that your not matching this correctly and that is it. I have demonstrated that this feature is stable and works as expected. Maybe its time for you to make a detailed video of what your doing... from beginning to end, not skipping any part. Without fully understanding what your really doing I am wasting my time.
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: joomla/Component-Builder#997
No description provided.