Post by rmullaney77 » Sun Sep 29, 2024 4:55 am

Goal: Creating a single extension with multiple controllers
Issue: All controllers show up at Admin > Extensions > Others

Folder structures attempted...
  • extension
    • name
      • admin
        • controller
          • other
            • primary.php
            • ancillary_one.php
            • ancillary_two.php
  • extension
    • name
      • admin
        • controller
          • other
            • primary.php
            • folder
              • ancillary_one.php
              • ancillary_two.php

Question: Is there a way for a single OC4 extension to...
  1. have multiple controllers
  2. show only "primary" in extension list
Note: If all the controllers were not as listed separate extensions it would be fine.

Hoping I do not have to place all routable methods in a single heavy-as-hell controller? :choke:
  • extension
    • name
      • admin
        • controller
          • other
            • primary.php (difficult to maintain)

User avatar
Active Member

Posts

Joined
Fri Nov 19, 2010 2:08 am
Location - Fort Payne, Alabama

Post by rmullaney77 » Sun Sep 29, 2024 9:25 pm

What I came up with since posting...

extension/name/admin/controller/startup/primary.php

Code: Select all

public function index(): void {
    $this->event->register('view/extension/other/before', new \Opencart\System\Engine\Action('extension/name/startup/primary.extensions'));
}

public function extensions(string &$route, array &$args, mixed &$output): void {
    foreach ($args['extensions'] as $key => $ext) {
        parse_str(parse_url(str_replace('&', '&', $ext['install']), PHP_URL_QUERY), $param);
        
        if ($param['extension'] == 'name' && $param['code'] != 'primary') {
            unset($args['extensions'][$key]);
        }
    }
}
Is there a better way?

User avatar
Active Member

Posts

Joined
Fri Nov 19, 2010 2:08 am
Location - Fort Payne, Alabama

Post by rmullaney77 » Sun Sep 29, 2024 10:21 pm

Startup controller needed one more method to adjust extension "categories" dropdown...

Code: Select all

public function marketplace(string &$route, array &$args, mixed &$output): void {
    foreach ($args['categories'] as $key => $category) {
        if ($category['code'] == 'other') {
            $this->load->language('extension/other/other');
            
            $args['categories'][$key]['text'] = sprintf('%s (%d)', $this->language->get('other_heading_title'), (int)preg_replace('/\D/', '', $category['text']) - count(glob('extension/name/admin/controller/other/' . '*.php')) - 1);
            
            break;
        }
    }
}
Unless someone has a better solution, I guess that wraps it up! Now I can keep developing my extension using separate controllers *woot*

User avatar
Active Member

Posts

Joined
Fri Nov 19, 2010 2:08 am
Location - Fort Payne, Alabama

Post by rmullaney77 » Mon Sep 30, 2024 10:19 pm

Unfortunately, the ancillary controllers are still shown before the extension is installed via extension list. So I conditionally append a script tag (removed via startup controller everywhere else) to heading_title primary controller language, that hides unwanted rows on page load, before startup events are active :-\ Not how I prefer to handle the problem, but it gets the job done for now...

Code: Select all

<?php
// Script to hide ancillary controller rows in extension list
$heading_title_script = '<script>$(function(){$(\'#extension a[href*="extension=name"]\').not(\'#extension a[href*="code=primary"]\').closest(\'tr\').hide()})</script>';

// Heading
$_['heading_title'] = 'Name' . (in_array($_GET['route'], array('marketplace/extension', 'extension/other'))  ? $heading_title_script : '');
Might revisit this for a master branch pull later if I can determine a widely-acceptable way for the extension list to handle complex extensions, without jumping through all these hoops.

User avatar
Active Member

Posts

Joined
Fri Nov 19, 2010 2:08 am
Location - Fort Payne, Alabama
Who is online

Users browsing this forum: No registered users and 4 guests