Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
drupal
Manage
Activity
Members
Labels
Plan
Wiki
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
project
drupal
Merge requests
!516
"README.md" did not exist on "6.x-1.4"
Issue
#3207782
: Figure out BC for jquery once by @drupal/once
Code
Review changes
Check out branch
Download
Patches
Plain diff
Closed
Issue
#3207782
: Figure out BC for jquery once by @drupal/once
issue/drupal-3207782:3207782-figure-out-bc
into
9.3.x
Overview
5
Commits
204
Pipelines
0
Changes
194
All threads resolved!
Hide all comments
Closed
Théodore Biadala
requested to merge
issue/drupal-3207782:3207782-figure-out-bc
into
9.3.x
4 years ago
Overview
5
Commits
204
Pipelines
0
Changes
194
All threads resolved!
Hide all comments
Expand
0
0
Merge request reports
Compare
9.3.x
version 11
6f03ba9e
3 years ago
version 10
6f03ba9e
3 years ago
version 9
413696cd
3 years ago
version 8
7ac9ccdb
3 years ago
version 7
ee50ba51
3 years ago
version 6
787da21b
3 years ago
version 5
9a0744cc
3 years ago
version 4
8ebd5b70
3 years ago
version 3
f3e83c9e
3 years ago
version 2
819895c2
3 years ago
version 1
146af219
4 years ago
9.3.x (base)
and
latest version
latest version
384184b7
204 commits,
3 years ago
version 11
6f03ba9e
203 commits,
3 years ago
version 10
6f03ba9e
8 commits,
3 years ago
version 9
413696cd
7 commits,
3 years ago
version 8
7ac9ccdb
6 commits,
3 years ago
version 7
ee50ba51
6 commits,
3 years ago
version 6
787da21b
5 commits,
3 years ago
version 5
9a0744cc
4 commits,
3 years ago
version 4
8ebd5b70
3 commits,
3 years ago
version 3
f3e83c9e
2 commits,
3 years ago
version 2
819895c2
1 commit,
3 years ago
version 1
146af219
1 commit,
4 years ago
194 files
+
343
−
6129
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
194
Search (e.g. *.vue) (Ctrl+P)
core/lib/Drupal/Core/Command/GenerateTheme.php deleted
100644 → 0
+
0
−
286
Options
<?php
namespace
Drupal\Core\Command
;
use
Drupal\Component\Serialization\Yaml
;
use
Drupal\Core\Extension\Extension
;
use
Drupal\Core\Extension\ExtensionDiscovery
;
use
Drupal\Core\File\FileSystem
;
use
Symfony\Component\Console\Command\Command
;
use
Symfony\Component\Console\Input\InputArgument
;
use
Symfony\Component\Console\Input\InputInterface
;
use
Symfony\Component\Console\Input\InputOption
;
use
Symfony\Component\Console\Output\OutputInterface
;
use
Symfony\Component\Console\Style\SymfonyStyle
;
use
Twig\Util\TemplateDirIterator
;
/**
* Generates a new theme based on latest default markup.
*/
class
GenerateTheme
extends
Command
{
/**
* The path for the Drupal root.
*
* @var string
*/
private
$root
;
/**
* {@inheritdoc}
*/
public
function
__construct
(
string
$name
=
NULL
)
{
parent
::
__construct
(
$name
);
$this
->
root
=
dirname
(
__DIR__
,
5
);
}
/**
* {@inheritdoc}
*/
protected
function
configure
()
{
$this
->
setName
(
'generate-theme'
)
->
setDescription
(
'Generates a new theme based on latest default markup.'
)
->
addArgument
(
'machine-name'
,
InputArgument
::
REQUIRED
,
'The machine name of the generated theme'
)
->
addOption
(
'name'
,
NULL
,
InputOption
::
VALUE_OPTIONAL
,
'A name for the theme.'
)
->
addOption
(
'description'
,
NULL
,
InputOption
::
VALUE_OPTIONAL
,
'A description of your theme.'
)
->
addOption
(
'path'
,
NULL
,
InputOption
::
VALUE_OPTIONAL
,
'The path where your theme will be created. Defaults to: themes'
)
->
addUsage
(
'custom_theme --name "Custom Theme" --description "Custom theme generated from a starterkit theme" --path themes'
);
}
/**
* {@inheritdoc}
*/
protected
function
execute
(
InputInterface
$input
,
OutputInterface
$output
)
{
$io
=
new
SymfonyStyle
(
$input
,
$output
);
// Change the directory to the Drupal root.
chdir
(
$this
->
root
);
// Path where the generated theme should be placed.
$destination_theme
=
$input
->
getArgument
(
'machine-name'
);
$default_destination
=
'themes'
;
$destination
=
trim
(
$input
->
getOption
(
'path'
)
?:
$default_destination
,
'/'
)
.
'/'
.
$destination_theme
;
if
(
is_dir
(
$destination
))
{
$io
->
getErrorStyle
()
->
error
(
"Theme could not be generated because the destination directory
$destination
exists already."
);
return
1
;
}
// Source directory for the theme.
$source_theme_name
=
'starterkit_theme'
;
if
(
!
$source_theme
=
$this
->
getThemeInfo
(
$source_theme_name
))
{
$io
->
getErrorStyle
()
->
error
(
"Theme source theme
$source_theme_name
cannot be found ."
);
return
1
;
}
$source
=
$source_theme
->
getPath
();
if
(
!
is_dir
(
$source
))
{
$io
->
getErrorStyle
()
->
error
(
"Theme could not be generated because the source directory
$source
does not exist."
);
return
1
;
}
$tmp_dir
=
$this
->
getUniqueTmpDirPath
();
$this
->
copyRecursive
(
$source
,
$tmp_dir
);
// Rename files based on the theme machine name.
$file_pattern
=
"/
$source_theme_name
\.(theme|[^.]+\.yml)/"
;
if
(
$files
=
@
scandir
(
$tmp_dir
))
{
foreach
(
$files
as
$file
)
{
$location
=
$tmp_dir
.
'/'
.
$file
;
if
(
is_dir
(
$location
))
{
continue
;
}
if
(
preg_match
(
$file_pattern
,
$file
,
$matches
))
{
if
(
!
rename
(
$location
,
$tmp_dir
.
'/'
.
$destination_theme
.
'.'
.
$matches
[
1
]))
{
$io
->
getErrorStyle
()
->
error
(
"The file
$location
could not be moved."
);
return
1
;
}
}
}
}
else
{
$io
->
getErrorStyle
()
->
error
(
"Temporary directory
$tmp_dir
cannot be opened."
);
return
1
;
}
// Info file.
$info_file
=
"
$tmp_dir
/
$destination_theme
.info.yml"
;
if
(
!
file_exists
(
$info_file
))
{
$io
->
getErrorStyle
()
->
error
(
"The theme info file
$info_file
could not be read."
);
return
1
;
}
$info
=
Yaml
::
decode
(
file_get_contents
(
$info_file
));
$info
[
'name'
]
=
$input
->
getOption
(
'name'
)
?:
$destination_theme
;
// Unhide hidden themes.
unset
(
$info
[
'hidden'
]);
$info
[
'core_version_requirement'
]
=
'^'
.
$this
->
getVersion
();
if
(
$description
=
$input
->
getOption
(
'description'
))
{
$info
[
'description'
]
=
$description
;
}
else
{
unset
(
$info
[
'description'
]);
}
// Replace references to libraries.
if
(
isset
(
$info
[
'libraries'
]))
{
$info
[
'libraries'
]
=
preg_replace
(
"/
$source_theme_name
(\/.*)/"
,
"
$destination_theme
$1"
,
$info
[
'libraries'
]);
}
if
(
isset
(
$info
[
'libraries-extend'
]))
{
foreach
(
$info
[
'libraries-extend'
]
as
$key
=>
$value
)
{
$info
[
'libraries-extend'
][
$key
]
=
preg_replace
(
"/
$source_theme_name
(\/.*)/"
,
"
$destination_theme
$1"
,
$info
[
'libraries-extend'
][
$key
]);
}
}
if
(
isset
(
$info
[
'libraries-override'
]))
{
foreach
(
$info
[
'libraries-override'
]
as
$key
=>
$value
)
{
if
(
isset
(
$info
[
'libraries-override'
][
$key
][
'dependencies'
]))
{
$info
[
'libraries-override'
][
$key
][
'dependencies'
]
=
preg_replace
(
"/
$source_theme_name
(\/.*)/"
,
"
$destination_theme
$1"
,
$info
[
'libraries-override'
][
$key
][
'dependencies'
]);
}
}
}
if
(
!
file_put_contents
(
$info_file
,
Yaml
::
encode
(
$info
)))
{
$io
->
getErrorStyle
()
->
error
(
"The theme info file
$info_file
could not be written."
);
return
1
;
}
// Replace references to libraries in libraries.yml file.
$libraries_file
=
"
$tmp_dir
/
$destination_theme
.libraries.yml"
;
if
(
file_exists
(
$libraries_file
))
{
$libraries
=
Yaml
::
decode
(
file_get_contents
(
$libraries_file
));
foreach
(
$libraries
as
$key
=>
$value
)
{
if
(
isset
(
$libraries
[
$key
][
'dependencies'
]))
{
$libraries
[
$key
][
'dependencies'
]
=
preg_replace
(
"/
$source_theme_name
(\/.*)/"
,
"
$destination_theme
$1"
,
$libraries
[
$key
][
'dependencies'
]);
}
}
if
(
!
file_put_contents
(
$libraries_file
,
Yaml
::
encode
(
$libraries
)))
{
$io
->
getErrorStyle
()
->
error
(
"The libraries file
$libraries_file
could not be written."
);
return
1
;
}
}
// Rename hooks.
$theme_file
=
"
$tmp_dir
/
$destination_theme
.theme"
;
if
(
file_exists
(
$theme_file
))
{
if
(
!
file_put_contents
(
$theme_file
,
preg_replace
(
"/(function )(
$source_theme_name
)(_.*)/"
,
"$1
$destination_theme
$3"
,
file_get_contents
(
$theme_file
))))
{
$io
->
getErrorStyle
()
->
error
(
"The theme file
$theme_file
could not be written."
);
return
1
;
}
}
// Rename references to libraries in templates.
$iterator
=
new
TemplateDirIterator
(
new
\RegexIterator
(
new
\RecursiveIteratorIterator
(
new
\RecursiveDirectoryIterator
(
$tmp_dir
),
\RecursiveIteratorIterator
::
LEAVES_ONLY
),
'/'
.
preg_quote
(
'.html.twig'
)
.
'$/'
));
foreach
(
$iterator
as
$template_file
=>
$contents
)
{
$new_template_content
=
preg_replace
(
"/(attach_library\(['
\"
)])
$source_theme_name
(\/.*['
\"
]\))/"
,
"$1
$destination_theme
$2"
,
$contents
);
if
(
!
file_put_contents
(
$template_file
,
$new_template_content
))
{
$io
->
getErrorStyle
()
->
error
(
"The template file
$template_file
could not be written."
);
return
1
;
}
}
if
(
!
rename
(
$tmp_dir
,
$destination
))
{
$io
->
getErrorStyle
()
->
error
(
"The theme could not be moved to the destination:
$destination
."
);
return
1
;
}
$output
->
writeln
(
sprintf
(
'Theme generated successfully to %s'
,
$destination
));
return
0
;
}
/**
* Copies files recursively.
*
* @param string $src
* A file or directory to be copied.
* @param string $dest
* Destination directory where the directory or file should be copied.
*
* @throws \RuntimeException
* Exception thrown if copying failed.
*/
private
function
copyRecursive
(
$src
,
$dest
):
void
{
// Copy all subdirectories and files.
if
(
is_dir
(
$src
))
{
if
(
!
mkdir
(
$dest
,
FileSystem
::
CHMOD_DIRECTORY
,
FALSE
))
{
throw
new
\RuntimeException
(
"Directory
$dest
could not be created"
);
}
$handle
=
opendir
(
$src
);
while
(
$file
=
readdir
(
$handle
))
{
if
(
$file
!=
"."
&&
$file
!=
".."
)
{
$this
->
copyRecursive
(
"
$src
/
$file
"
,
"
$dest
/
$file
"
);
}
}
closedir
(
$handle
);
}
elseif
(
is_link
(
$src
))
{
symlink
(
readlink
(
$src
),
$dest
);
}
elseif
(
!
copy
(
$src
,
$dest
))
{
throw
new
\RuntimeException
(
"File
$src
could not be copied to
$dest
"
);
}
// Set permissions for the directory or file.
if
(
!
is_link
(
$dest
))
{
if
(
is_dir
(
$dest
))
{
$mode
=
FileSystem
::
CHMOD_DIRECTORY
;
}
else
{
$mode
=
FileSystem
::
CHMOD_FILE
;
}
if
(
!
chmod
(
$dest
,
$mode
))
{
throw
new
\RuntimeException
(
"The file permissions could not be set on
$src
"
);
}
}
}
/**
* Generates a path to a temporary location.
*
* @return string
*/
private
function
getUniqueTmpDirPath
():
string
{
return
sys_get_temp_dir
()
.
'/drupal-starterkit-theme-'
.
uniqid
(
md5
(
microtime
()),
TRUE
);
}
/**
* Gets theme info using the theme name.
*
* @param string $theme
* The machine name of the theme.
*
* @return \Drupal\Core\Extension\Extension|null
*/
private
function
getThemeInfo
(
string
$theme
):
?
Extension
{
$extension_discovery
=
new
ExtensionDiscovery
(
$this
->
root
,
FALSE
,
[]);
$themes
=
$extension_discovery
->
scan
(
'theme'
);
if
(
!
isset
(
$themes
[
$theme
]))
{
return
NULL
;
}
return
$themes
[
$theme
];
}
/**
* Gets the current Drupal major version.
*
* @return string
*/
private
function
getVersion
():
string
{
return
explode
(
'.'
,
\Drupal
::
VERSION
)[
0
];
}
}
Loading