🇦🇹Austria @maxilein

Account created on 10 November 2010, over 14 years ago
#

Recent comments

🇦🇹Austria maxilein

Changed to Major and BUG because it causes a lot of headaches outside of gin...

🇦🇹Austria maxilein

Also see this comment. https://www.drupal.org/project/save_edit/issues/3528935#comment-16138378 🐛 Save_edit in GIN admin theme in Drupal CMS (11) hardly accessible Active
It shows that is impossible to rely on gin functionality in this matter.

🇦🇹Austria maxilein

Sorry I was in the wrong. I used Version: 8.x-1.8 not the current dev version of save_ edit

🇦🇹Austria maxilein

Thinking about that issue and finding others having problems with it (e.g. https://www.drupal.org/project/workflow/issues/3458569 Support Gin action item Active )- I have to say that I get the impression that there is something inherently wrong with the gin approach of putting its own functionality buttons above other modules.
Requiring the other modules to flag theme(!) specific attributes will only clutter the drupal code and cause
"Latest version of Gin Admin theme hides actions behind a more actions button unless it is identified as a #gin_action_item."

In how many modules do you expect to find #gin_action_item in the code?!

So I suggest:

Treat all functionality of any module as equal. Therefore making it configurable by admins: per entity type which buttons appear outside of the more actions menu and in which order.

I also think it is a major issue, since it concerns many other modules.

🇦🇹Austria maxilein

Whatever this line does
if ($config->get('gin_primary')) {: Maybe the problem is that I use gin for admin theme (not main theme) and to edit content?

🇦🇹Austria maxilein

If I change save_edit.module line 57:

     if ($config->get('gin_primary')) {
        $form['actions']['save_edit']['#gin_action_item'] = TRUE;
      }

to

      /*if ($config->get('gin_primary')) {*/
        $form['actions']['save_edit']['#gin_action_item'] = TRUE;
      /*}*/

it works and is visible alongside the save button.

🇦🇹Austria maxilein

A rookie question: Does ConfigEntityBundleBase also comprise blocks and paragraphs?

🇦🇹Austria maxilein

Mentioning this issue may cause problems in the future for some.
https://www.drupal.org/project/drupal/issues/3070381 🐛 Base theme libraries may be output in reverse order Active

🇦🇹Austria maxilein

Thank you as always for your help.

Just to report back: I cannot reproduce the erratic behaviour. I had played with the custom.css without css aggregation disabled for quite some time.
I then changed my maxilein.libraries.yml according to https://www.drupal.org/project/drupal/issues/3070381 🐛 Base theme libraries may be output in reverse order Active to this: adding dependencies.. etc. did not change anything.
Then I re-added the weight. Changed nothing...
So out of desperation I enabled css aggregation. Changed nothing.
I played around with the settings, drush cr.
Disabled css aggregation again.
Suddenly it worked. I really don't know why.
I even tried to remove the dependency and in the end the weight only would also work.
So I still left my maxilein.libraries.yml like this:

maxilein-global:
  css:
    theme:
     css/maxilein-style.css: {weight: 400}
  dependencies:
    - solo/solo-global
  js:
    js/maxilein-script.js: {}
🇦🇹Austria maxilein

It completely varies by element. I cannot detect a pattern. Sometimes there are 3 or more other css loaded after my custom css.

🇦🇹Austria maxilein

maybe this helps: https://www.drupal.org/forum/support/post-installation/2023-12-19/solved...

Or this https://www.drupal.org/project/drupal/issues/3467860 🐛 Logic error in Drupal's lazy load for asset aggregation Active

And here ( https://www.drupal.org/node/3473558 ) it says: "In general, libraries should avoid setting custom weights where possible, and rely on properly declaring dependencies between libraries instead wherever possible."

And another very long standing issue here: https://www.drupal.org/project/drupal/issues/1945262 📌 Replace custom weights with dependencies in library declarations; introduce "before" and "after" for conditional ordering Needs work

🇦🇹Austria maxilein

paragraphs-bundles-custom.css still loads after maxilein-style.css
no matter whether it is in maxilein.info.yml or maxilein.libraries.yml
many drush cr ...

🇦🇹Austria maxilein

Thank you. But you are meaning in the maxilein.libraries.yml, right?

🇦🇹Austria maxilein

Making title more descriptive

🇦🇹Austria maxilein

Since it is already working that way we can also add the drupal_user permissions later - or during review.

🇦🇹Austria maxilein

To make it easier for anyone to find the open questions:

TODO: I have to mention that with this config I could only get the solr User to connect from search_api - not the drupal_user. I am missing some permissions in the security.json. (see // ---- Permissions for 'drupal_role' for Collection 'core2025' ---- above)
Someone can please point to the correct settings for the drupal_user here! thank you.

🇦🇹Austria maxilein

I would also like to mention this issue: it may be a solution - at least temporary https://www.drupal.org/project/search_api/issues/3069515 💬 Silence the warnings: An overlong word (more than 50 characters) ... Needs work

🇦🇹Austria maxilein

I run into the same problems using search_api_solr. When large base64 encoded images are embedded in the body it makes the SOLR go out of bounds. Probably because I am using ngramstring which has a quardratic memory consumption.
Maybe an option to explicitly treat base64 encoded stuff in strings would be an idea.

I am using Drupal 11.1.7 and SOLR 9.8.1

🇦🇹Austria maxilein

I would like to add this error in case someone else falls into this "trap". And by searching for this error the solution might come up faster for someone else ... than it did for me.

The solution was to add
SOLR_OPTS="$SOLR_OPTS -Dsolr.config.lib.enabled=true"
in /etc/default/solr.in.sh

After installing a new SOLR 9.8.1 I received the following error right after upload of the Drupal config.xml

org.apache.solr.core.SolrCoreInitializationException: SolrCore 'corename' is not available due to init failure: Could not load conf for core fuez2025: Can't load schema /var/solr/data/fuez2025/conf/schema.xml: Plugin init failure for [schema.xml] fieldType \"collated_en\"

"error":{
    "metadata":["error-class","org.apache.solr.core.SolrCoreInitializationException","root-error-class","java.lang.ClassNotFoundException"],
    "msg":"SolrCore 'corename' is not available due to init failure: Could not load conf for core corename: Can't load schema /var/solr/data/corename/conf/schema.xml: Plugin init failure for [schema.xml] fieldType \"collated_en\":  Error loading class 'solr.ICUCollationField'",
    "trace":"org.apache.solr.core.SolrCoreInitializationException: SolrCore 'corename' is not available due to init failure: Could not load conf for core corename: Can't load schema /var/solr/data/corename/conf/schema.xml: Plugin init failure for [schema.xml] fieldType \"collated_en\":  Error loading class 'solr.ICUCollationField'\n\tat org.apache.solr.core.CoreContainer.getCore(CoreContainer.java:2298)\n\tat org.apache.solr.core.CoreContainer.getCore(CoreContainer.java:2267)\n\tat org.apache.solr.servlet.HttpSolrCall.init(HttpSolrCall.java:239)\n\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:523)\n\tat org.apache.solr.servlet.SolrDispatchFilter.dispatch(SolrDispatchFilter.java:241)\n\tat org.apache.solr.servlet.SolrDispatchFilter.lambda$doFilterRetry$0(SolrDispatchFilter.java:198)\n\tat org.apache.solr.servlet.ServletUtils.traceHttpRequestExecution2(ServletUtils.java:227)\n\tat org.apache.solr.servlet.ServletUtils.rateLimitRequest(ServletUtils.java:197)\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilterRetry(SolrDispatchFilter.java:192)\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:181)\n\tat javax.servlet.http.HttpFilter.doFilter(HttpFilter.java:97)\n\tat org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:210)\n\tat org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)\n\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:149)\n\tat org.eclipse.jetty.server.handler.InetAccessHandler.handle(InetAccessHandler.java:228)\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:141)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)\n\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:301)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)\n\tat org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:822)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)\n\tat org.eclipse.jetty.server.Server.handle(Server.java:563)\n\tat org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)\n\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)\n\tat org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:461)\n\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)\n\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)\n\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)\n\tat org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:193)\n\tat org.eclipse.jetty.http2.HTTP2Connection.produce(HTTP2Connection.java:208)\n\tat org.eclipse.jetty.http2.server.HTTP2ServerConnection.onOpen(HTTP2ServerConnection.java:116)\n\tat org.eclipse.jetty.io.AbstractEndPoint.upgrade(AbstractEndPoint.java:451)\n\tat org.eclipse.jetty.server.NegotiatingServerConnection.onFillable(NegotiatingServerConnection.java:125)\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)\n\tat org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:558)\n\tat org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:379)\n\tat org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:146)\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)\n\tat org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)\n\tat java.base/java.lang.Thread.run(Thread.java:1583)\nCaused by: org.apache.solr.common.SolrException: Could not load conf for core corename: Can't load schema /var/solr/data/corename/conf/schema.xml: Plugin init failure for [schema.xml] fieldType \"collated_en\":  Error loading class 'solr.ICUCollationField'\n\tat org.apache.solr.core.ConfigSetService.loadConfigSet(ConfigSetService.java:291)\n\tat org.apache.solr.core.CoreContainer.createFromDescriptor(CoreContainer.java:1735)\n\tat org.apache.solr.core.CoreContainer.lambda$loadInternal$12(CoreContainer.java:1080)\n\tat com.codahale.metrics.InstrumentedExecutorService$InstrumentedRunnable.run(InstrumentedExecutorService.java:212)\n\tat org.apache.solr.common.util.ExecutorUtil$MDCAwareThreadPoolExecutor.lambda$execute$0(ExecutorUtil.java:380)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)\n\t... 1 more\nCaused by: org.apache.solr.common.SolrException: Can't load schema /var/solr/data/corename/conf/schema.xml: Plugin init failure for [schema.xml] fieldType \"collated_en\":  Error loading class 'solr.ICUCollationField'\n\tat org.apache.solr.schema.IndexSchema.readSchema(IndexSchema.java:663)\n\tat org.apache.solr.schema.IndexSchema.<init>(IndexSchema.java:193)\n\tat org.apache.solr.schema.IndexSchemaFactory.create(IndexSchemaFactory.java:109)\n\tat org.apache.solr.core.ConfigSetService.createIndexSchema(ConfigSetService.java:370)\n\tat org.apache.solr.core.ConfigSetService.lambda$loadConfigSet$0(ConfigSetService.java:281)\n\tat org.apache.solr.core.ConfigSet.<init>(ConfigSet.java:49)\n\tat org.apache.solr.core.ConfigSetService.loadConfigSet(ConfigSetService.java:277)\n\t... 7 more\nCaused by: org.apache.solr.common.SolrException: Plugin init failure for [schema.xml] fieldType \"collated_en\":  Error loading class 'solr.ICUCollationField'\n\tat org.apache.solr.util.plugin.AbstractPluginLoader.load(AbstractPluginLoader.java:179)\n\tat org.apache.solr.schema.IndexSchema.readSchema(IndexSchema.java:538)\n\t... 13 more\nCaused by: org.apache.solr.common.SolrException:  Error loading class 'solr.ICUCollationField'\n\tat org.apache.solr.core.SolrResourceLoader.findClass(SolrResourceLoader.java:553)\n\tat org.apache.solr.core.SolrResourceLoader.newInstance(SolrResourceLoader.java:615)\n\tat org.apache.solr.core.SolrResourceLoader.newInstance(SolrResourceLoader.java:609)\n\tat org.apache.solr.schema.FieldTypePluginLoader.create(FieldTypePluginLoader.java:74)\n\tat org.apache.solr.schema.FieldTypePluginLoader.create(FieldTypePluginLoader.java:43)\n\tat org.apache.solr.util.plugin.AbstractPluginLoader.load(AbstractPluginLoader.java:144)\n\t... 14 more\nCaused by: java.lang.ClassNotFoundException: solr.ICUCollationField\n\tat java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)\n\tat java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:593)\n\tat java.base/java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:872)\n\tat java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)\n\tat java.base/java.lang.Class.forName0(Native Method)\n\tat java.base/java.lang.Class.forName(Class.java:534)\n\tat java.base/java.lang.Class.forName(Class.java:513)\n\tat org.apache.solr.core.SolrResourceLoader.findClass(SolrResourceLoader.java:537)\n\t... 19 more\n",

    "code":500
🇦🇹Austria maxilein

It is still too short to reflect a naming convention that makes sense in a broader context on a complex site...
Not even windows is fixed to 255 limt anylonger...
And what does a table field size have to do with the filesystem anyway?

🇦🇹Austria maxilein

Thank you.
Let me explain my observation - an outside view so to say.

I added the field decimal, because I needed a place for huge numbers with not so many positions behind the comma.
Then I had to realize that a field called decimal is very much limited in comparison to what I expected, or from my experience with other decimal functionality in other system would have expected.
That was my confusion number one.

Then I learned I can configure the field upon its creation. And before this validation bug here - or better without realizing that again - it was not problem to set the gui to whatever I needed. A huge number with a few digits behind the comma.
Entering data caused numbers to be crunched ... we all know that story here.

Then you wonder what to do and how it all depends on each other.

The default database allows for much more digits before and after the comma than default Drupal.
In my opinion that is not good. It is confusion number one.
Then you realize that also php may have a limit inbetween. That is confusion number three.

In my opinion we should make that clear somehow.
I think Drupal should ask during install how the user wants it to be set.
e.g.
DB limit is ...
php limit is ...
Drupal default is ...
Would you like to use Drupal default precision/scale for decimal fields or would you like to increase the default to the php and DB limits.

Then at least it would be transparent what happens here.

The next problem is the intransparent limitation of this patch. I can set some precicion/scale during field creation and it may crash because of underlying system differences ... which were not obvious during field creation.

Why should this patch not be adjusted to system parameter settings? it does not make sence to me to keep an artificially limited number of digits before or after the comma it the system already provides for that bandwidth.

And btw: thank you all very much for your efforts!

The standard setting does not a

🇦🇹Austria maxilein

#372 I completely agree.
And I don't understand this from #370 "We shouldn't make this field value dependent on an environment specific setting. It needs to be distinct."

We have three layers:
Database - php - drupal/gui

Why should they be distinct from each other?!

if php sends something too large for the db -> error.
If drupal sends something wrongly scaled -> error.
...

In my opinion we should specify rules on how they need to be in sync to each other.

🇦🇹Austria maxilein

Everything is fine for me. You are the expert. I am not so deep in Drupal code in order to make these judgements.

🇦🇹Austria maxilein

And don't forget #17. It seems to be a rare trap.

🇦🇹Austria maxilein

Please someone check that code above and here are example cases.

// Example 1: Stage is a direct subdirectory
$stage1 = '/var/www/html/myproject/staging';
$active1 = '/var/www/html/myproject';
echo "Example 1: " . (isStageSubdirectoryOfActive($stage1, $active1) ? 'true' : 'false') . "\n"; // Output: true

// Example 2: Stage is nested deeper
$stage2 = '/var/www/html/myproject/staging/sub/folder';
$active2 = '/var/www/html/myproject';
echo "Example 2: " . (isStageSubdirectoryOfActive($stage2, $active2) ? 'true' : 'false') . "\n"; // Output: true

// Example 3: Paths are identical
$stage3 = '/var/www/html/myproject';
$active3 = '/var/www/html/myproject';
echo "Example 3: " . (isStageSubdirectoryOfActive($stage3, $active3) ? 'true' : 'false') . "\n"; // Output: false

// Example 4: Stage is a parent directory (or unrelated)
$stage4 = '/var/www/html';
$active4 = '/var/www/html/myproject';
echo "Example 4: " . (isStageSubdirectoryOfActive($stage4, $active4) ? 'true' : 'false') . "\n"; // Output: false

// Example 5: Unrelated paths
$stage5 = '/etc/nginx';
$active5 = '/var/www/html';
echo "Example 5: " . (isStageSubdirectoryOfActive($stage5, $active5) ? 'true' : 'false') . "\n"; // Output: false

// Example 6: Partial match, but not a directory boundary
$stage6 = '/var/www/html_extra';
$active6 = '/var/www/html';
echo "Example 6: " . (isStageSubdirectoryOfActive($stage6, $active6) ? 'true' : 'false') . "\n"; // Output: false

// Example 7: Windows-style paths
$stage7 = 'C:\\Users\\Test\\My Documents\\Stage';
$active7 = 'C:\\Users\\Test\\My Documents';
echo "Example 7: " . (isStageSubdirectoryOfActive($stage7, $active7) ? 'true' : 'false') . "\n"; // Output: true

// Example 8: Mixed separators
$stage8 = 'C:/Users/Test/My Documents/Stage/Sub';
$active8 = 'C:\\Users\\Test\\My Documents';
echo "Example 8: " . (isStageSubdirectoryOfActive($stage8, $active8) ? 'true' : 'false') . "\n"; // Output: true

// Example 9: Trailing slashes
$stage9 = '/var/www/html/myproject/staging/';
$active9 = '/var/www/html/myproject/';
echo "Example 9: " . (isStageSubdirectoryOfActive($stage9, $active9) ? 'true' : 'false') . "\n"; // Output: true

// Example 10: Root directory cases
$stage10a = '/var/log';
$active10a = '/';
echo "Example 10a (Root): " . (isStageSubdirectoryOfActive($stage10a, $active10a) ? 'true' : 'false') . "\n"; // Output: true

$stage10b = '/';
$active10b = '/';
echo "Example 10b (Root): " . (isStageSubdirectoryOfActive($stage10b, $active10b) ? 'true' : 'false') . "\n"; // Output: false


🇦🇹Austria maxilein

If you add this function to modules\contrib\automatic_updates\package_manager\src\PathLocator.php

 /**
 * Checks if a given path string ($stage) represents a subdirectory
 * of another path string ($active).
 *
 * This function compares absolute path strings, normalizes directory separators,
 * and handles edge cases like identical paths or root directories.
 * It does *not* check if the paths actually exist on the filesystem,
 * it purely performs a string comparison.
 *
 * @param string $stage The absolute path string that might be a subdirectory.
 * @param string $active The absolute path string that might be the parent directory.
 *
 * @return bool Returns true if $stage is a subdirectory of $active, false otherwise.
 */
    public function isStageSubdirectoryOfActive(string $stage, string $active): bool
    {
        // 1. Normalize directory separators to '/' for consistent comparison
        $stageNormalized = str_replace('\\', '/', $stage);
        $activeNormalized = str_replace('\\', '/', $active);

        // 2. If the normalized paths are identical, stage is not a *sub*directory.
        if ($stageNormalized === $activeNormalized) {
            return false;
        }

        // 3. Prepare the active path prefix for comparison.
        //    For a path to be a subdirectory, it must start with the parent path
        //    followed by a directory separator.
        //    We ensure the active path ends with a '/' for the check,
        //    unless the active path *is* the root directory itself ('/').
        $activePrefix = rtrim($activeNormalized, '/') . '/';
        if ($activeNormalized === '/') {
             // If active is the root, the prefix should just be '/'
            $activePrefix = '/';
        }

        // 4. Check if the normalized stage path *starts with* the active path prefix.
        //    Using strpos() === 0 is an efficient way to check for "starts with".
        //    Example 1: stage="/var/log/nginx", active="/var/log"
        //       -> stageNormalized="/var/log/nginx", activePrefix="/var/log/"
        //       -> strpos("/var/log/nginx", "/var/log/") === 0 -> TRUE
        //    Example 2: stage="/var/log", active="/var/log"
        //       -> Handled by check #2 -> FALSE
        //    Example 3: stage="/var/logs", active="/var/log"
        //       -> stageNormalized="/var/logs", activePrefix="/var/log/"
        //       -> strpos("/var/logs", "/var/log/") === false -> FALSE
        //    Example 4: stage="/var/log/nginx/error.log", active="/var/log"
        //       -> stageNormalized="/var/log/nginx/error.log", activePrefix="/var/log/"
        //       -> strpos("/var/log/nginx/error.log", "/var/log/") === 0 -> TRUE
        //    Example 5: stage="/home/user", active="/"
        //       -> stageNormalized="/home/user", activePrefix="/"
        //       -> strpos("/home/user", "/") === 0 -> TRUE

        if (strpos($stageNormalized, $activePrefix) === 0) {
            // It starts with the correct prefix, confirming it's inside the active directory.
            // The check in step 2 already ensured they aren't identical.
            return true;
        }

        // If the stage path doesn't start with the active prefix, it's not a subdirectory.
        return false;
    }

And then change ...modules\contrib\automatic_updates\package_manager\src\Validator\StageNotInActiveValidator.php to

  /**
   * Check if staging root is a subdirectory of active.
   */
  public function validate(PreOperationStageEvent $event): void {
    $project_root = $this->pathLocator->getProjectRoot();
    $staging_root = $this->pathLocator->getStagingRoot();
    
    if ($this->pathLocator->isStageSubdirectoryOfActive($staging_root, $project_root) == true )
    {
      $message = $this->t("Stage directory is a subdirectory of the active directory.");
      $currentconfiginfo = $message . " STAGE: " . $staging_root . " ACTIVE ROOT: " . $project_root;
      $event->addError([$currentconfiginfo]);
    }
  }

the error goes away.

And it seems that the comparison logic of paths does work. But I have not tested any other cases than mine.
I will post examples in the next comment. Can someone please convert them into test cases?

Attached is a patch to the 3.1.7 of automatic_updates contrib module.

🇦🇹Austria maxilein

Thinking about it ACTIVE ROOT: /var/www would correspond to my composer.json location ( see structure above #7)

That seems ok. But I wonder if it would be reliable in all cases because in modules\contrib\automatic_updates\package_manager\src\PathLocator.php the function

  public function getProjectRoot(): string {
    // Assume that the vendor directory is immediately below the project root.
    return realpath($this->getVendorDirectory() . DIRECTORY_SEPARATOR . '..');
  }

has a comment making an assumption about the vender directory being below ...
What if it is somewhere else? Should we check for this assumption also - and at least warn that this check will not work if that is not the case?

🇦🇹Austria maxilein

Ok. I have tried to make visible what the validator does by adding these lines (in bold):
...modules\contrib\automatic_updates\package_manager\src\Validator\StageNotInActiveValidator.php
lines 38+39

public function validate(PreOperationStageEvent $event): void {
$project_root = $this->pathLocator->getProjectRoot();
$staging_root = $this->pathLocator->getStagingRoot();
if (str_starts_with($staging_root, $project_root)) {
$message = $this->t("Stage directory is a subdirectory of the active directory.");
$currentconfiginfo = $message . " STAGE: " . $staging_root . " ACTIVE ROOT: " . $project_root;
$event->addError([$currentconfiginfo]);
}
}

The output gives:

Stage directory is a subdirectory of the active directory. STAGE: /var/www_tmp/.package_managerX...Y ACTIVE ROOT: /var/www

And that shows that str_starts_with just does not produce a proper result.

🇦🇹Austria maxilein

The error message is not understandable. It does not make sense to talk about a directory called staging when there is no such folder in real Drupal folder structure.
In oder to make it more easy to grasp and administer without deep knowledge add the path in question that should be moved.

I could not find any documentation on the prerequisites for the new update module. Can someone point into that directions please.

🇦🇹Austria maxilein

Moving the tmp directory out from beneath the composer.json file location does not make the error go away.

moving it from /var/www/tmp
up to a new folder
$settings['file_temp_path'] = '/var/www_tmp';

Any other from php reported tmp directories are in on the testsystem.
/tmp

So I do not understand the error message. The message or check must be wrong.

OR is the Stage directory something completely different. like the sync folder?!

🇦🇹Austria maxilein

Here is what I learned asking myself how I came to the conclusion it was the recommended place:

Drupal 11 was upgraded from a site I originally installed using Drupal 9 and then I adapted the folder structure with Drupal 10.

The drupal/recommended-project Composer template used to sets up the following general structure:

your-project-name/
├── composer.json # Defines project dependencies, scripts, etc.
├── composer.lock # Locks dependency versions.
├── config/ # Often used for configuration management (e.g., config/sync).
│ └── sync/ # Default location for configuration sync.
├── drush/ # Drush site aliases, commands, and configuration.
├── vendor/ # Composer-managed dependencies (core, contrib modules, themes, PHP libraries). Not committed to Git.
├── web/ # The web server's document root (sometimes called docroot, public_html, etc.).
│ ├── core/ # Drupal core files (managed by Composer).
│ ├── index.php # Drupal's front controller.

There isn't a predefined tmp folder in the standard drupal/recommended-project structure.
Its location is determined by the setting found in Admin > Configuration > Media > File system.  
But most of the recommendations derive from web server configuration: It's best practice to explicitly configure a path outside the web root (web/) that is writable by the web server.

So I always figured that the composer.json above all folders is a safe bet - if the web server's root location is below it.
In my case the web server cannot access the folder where the composer.json file is located, because it is above the permissions of the web folder.
So a /tmp folder which is on the same level as the /web should be safe.
Why is it a problem that the /tmp is below the composer.json?

BTW: Here they call the /web structures Base-Level Directories: https://www.drupal.org/docs/getting-started/understanding-drupal/directo... . But htere is no mention of a tmp folder in regards to the new update manager functionality.
Once this is cleared up we should not forget to add documentation there.

🇦🇹Austria maxilein

Thank you. For the example below I added /active_directory in the structure.

/../active_directory/composer.json

/../active_directory/web/ (= Drupal) index.php

/../active_directory/web/vendor
/../active_directory/web/tmp
/../active_directory/web/recipes
/../active_directory/web/private

wasn't this the recommended structure until Drupal 9 or 10?

🇦🇹Austria maxilein

Maybe these errors are connected to this long standing issue: https://www.drupal.org/project/drupal/issues/2230909 🐛 Simple decimals fail to pass validation Needs work

🇦🇹Austria maxilein

I don't know if aligning menus and text separately should be another feature with its own dropdown or if it the entire content should be right aligned.
The menu is right aligning if I uncheck display:flex; - but also other elements...

🇦🇹Austria maxilein

Thanks a lot again! Looks great thank you.
It right aligns all texts like "Powered by Drupal" or the headings of a Menu.

But the menu itself remains flexed and centered inside the block. Pls. see screenshot.

🇦🇹Austria maxilein

I just realized that this bug is only if Header region and Main Menu region are NOT flipped (=default).
If header and main menu are flipped (as in screenshot the bug is not happening).
Very interesting.
In the current dev. version from about an hour ago the bug is gone.
I'll test further.

🇦🇹Austria maxilein

Thank you. It works beautifully.
By the way: thank you for your quick responses. And I have rarely seen such a clean and well organized theme like yours!
it is really impressive.

🇦🇹Austria maxilein

Here is a step by step description showing settings + result on each page.

🇦🇹Austria maxilein

You don't read my text or I don't understand what you are saying:

You say: "The logo option has no relationship with the menu". And by the design you chose I think it should be that way.

BUT there is a bug: The logo options is the ONLY way to also move the menu to the right! The drop-down alone is dead.

🇦🇹Austria maxilein

it is fine for me as it is.
But someone else might think that the dropdown does nothing - if they don't tick the logo option

🇦🇹Austria maxilein

otherwise it stays left aligned even though right is selected

🇦🇹Austria maxilein

the menu only right aligns when the checkbox for the logo is ticked

🇦🇹Austria maxilein

Thanks for your feedback.
I am using latest Drupal CMS and latest solo.dev - both without customization and no extra modules enabled.

But your screenshots helped a lot to narrow the issue down:
There is a difference if a menu entry has children or not.
If it has no child the error occurs.
Please see screenshots.

🇦🇹Austria maxilein

Thank you. Fantastic!
I tried it of course right away. The result is exactly what I wanted (including this issue Logo and Main Menu in the same horizontal height 💬 Logo and Main Menu in the same horizontal height Active ): Logo left aligned, Main Menu to the right.

Perfect for me. This issue alone seems to solve both this issue and the one mentioned above.

But here is the catch for anintuitive understanding of the theme configuration: the dropdown by itself does not right align the menu. In fact it does not seem to do anything.
If you look at the attached screenshots: the menu only right aligns when the checkbox for the logo is ticked.

🇦🇹Austria maxilein

if I add

align-items: center;
to

@media (min-width: 62rem) {
.solo-inner .navigation__responsive {
display: flex !important;
flex-wrap: wrap;
align-items: center;
}
}

it is correctly aligned in the menu.
But I am not sure this is the right position to add it without breaking anything else ...
please check...

🇦🇹Austria maxilein

Thank you!
I would appreciate it very much if you could make the changes. I don't even have git installed ...

🇦🇹Austria maxilein

We are using it for years.
Please take the D11 patch from the issue 📌 Drupal 11 compatibility Active and make a new release. It is working on D11.1.5 just fine.

🇦🇹Austria maxilein

Following the https://www.drupal.org/node/3375748 API changes and therefore changing line 18 in SimplePercentageItem.php from

* category = @Translation("number"),

to

* category = "number",

fixes the issue.

🇦🇹Austria maxilein

How about some log messages?

"view xy about to be deleted by module xy uninstall."

"view xy's configuration export BEFORE changes: "

"view xy's configuration export BEFORE changes: "

"view xy deleted by module xy uninstall. see previous log messages for configuration changes made."

🇦🇹Austria maxilein

hm, ... it works if you just use

composer require 'drupal/views_dependent_filters

🇦🇹Austria maxilein

I had some left overs from this module. It was listed as unsupported, but was nowhere to be found in the file system or comopser.json...

composer remove drupal/eca_context-eca_context (as mentined above) helped me get rid of that finally...

🇦🇹Austria maxilein

Same here:

composer require 'drupal/views_dependent_filters:^1.3'
./composer.json has been updated
Running composer update drupal/views_dependent_filters
Gathering patches for root package.
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Root composer.json requires drupal/views_dependent_filters ^1.3 -> satisfiable by drupal/views_dependent_filters[1.3.0].
- drupal/views_dependent_filters 1.3.0 requires drupal/core ^8.8 || ^9 || ^10 -> found drupal/core[8.8.0, ..., 8.9.20, 9.0.0, ..., 9.5.11, 10.0.0, ..., 10.4.4] but the package is fixed to 11.1.3 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.

Production build 0.71.5 2024