updated plugin Simple Local Avatars version 2.8.3

This commit is contained in:
KawaiiPunk 2025-04-29 21:20:02 +00:00 committed by Gitium
parent fd76ba0cbe
commit c950632407
122 changed files with 5001 additions and 115 deletions

View File

@ -0,0 +1,22 @@
#!/bin/bash
# Script directory and filename
SCRIPT_DIR="$(dirname "$0")"
SCRIPT_NAME="$(basename "$0")"
# Check for the required argument
if [ "$#" -ne 1 ]; then
echo "Usage: $0 New_Namespace"
exit 1
fi
NEW_NAMESPACE="$1"
# Use find to get all files recursively from the script's directory, excluding the script itself
find "$SCRIPT_DIR" -type f \( -name "*.php" -o -name "*.json" \) ! -name "$SCRIPT_NAME" | while read -r file; do
echo $file
# Use perl for the replacement in each file
perl -pi -e "s/WP_Compat_Validation_Tool/$NEW_NAMESPACE/g" "$file"
done
cd 10up-lib/wp-compat-validation-tool && rm -rf .git .github .gitignore composer.json composer.lock CHANGELOG.md CONTRIBUTING.md README.md LICENSE.md CODE_OF_CONDUCT.md CREDITS.md

View File

@ -0,0 +1,169 @@
<?php
namespace SimpleLocalAvatarsValidator;
class Validator {
/**
* Array of checks.
*
* @var array
*/
private $checklist = array();
/**
* Array of error messages
*
* @var string[]
*/
private $messages = array();
/**
* Constructor function.
*/
public function __construct() {
$this->checklist = array(
'plugin_name' => array(
'value' => '',
'required' => true,
),
'php_min_required_version' => array(
'value' => '',
'required' => false,
),
'php_max_required_version' => array(
'value' => '',
'required' => false,
),
'wp_min_required_version' => array(
'value' => '',
'required' => false,
),
'wp_max_required_version' => array(
'value' => '',
'required' => false,
),
);
}
/**
* Sets the plugin name.
*
* @param string $value Plugin name.
* @return Validator
*/
public function set_plugin_name( $value = '' ) {
$this->checklist['plugin_name']['value'] = $value;
return $this;
}
/**
* Sets the minimum PHP version supported by a plugin.
*
* @param string $value Minimum PHP version.
* @return Validator
*/
public function set_php_min_required_version( $value = '' ) {
$this->checklist['php_min_required_version']['value'] = $value;
return $this;
}
/**
* Sets the maximum PHP version supported by a plugin.
*
* @param string $value Maximum PHP version.
* @return Validator
*/
public function set_php_max_required_version( $value = '' ) {
$this->checklist['php_max_required_version']['value'] = $value;
return $this;
}
/**
* Sets the minimum WordPress version supported by a plugin.
*
* @param string $value Minimum WordPress version.
* @return Validator
*/
public function set_wordpress_min_required_version( $value = '' ) {
$this->checklist['wp_min_required_version']['value'] = $value;
return $this;
}
/**
* Sets the maximum WordPress version supported by a plugin.
*
* @param string $value Maximum WordPress version.
* @return Validator
*/
public function set_wordpress_max_required_version( $value = '' ) {
$this->checklist['wp_max_required_version']['value'] = $value;
return $this;
}
/**
* Returns true if the plugin meets all compatibility checks, false otherwise.
*
* @return boolean
*/
public function is_plugin_compatible() {
foreach ( $this->checklist as $item_name => $item_details ) {
if ( $item_details['required'] && empty( $item_details['value'] ) ) {
return false;
}
switch ( $item_name ) {
case 'php_min_required_version':
if ( ! empty( $item_details['value'] ) && version_compare( phpversion(), $item_details['value'], '<' ) ) {
$this->messages[] = sprintf( esc_html__( 'The minimum PHP version required is %s' ), $item_details['value'] );
}
break;
case 'php_max_required_version':
if ( ! empty( $item_details['value'] ) && version_compare( phpversion(), $item_details['value'], '>' ) ) {
$this->messages[] = sprintf( esc_html__( 'The maximum PHP version supported is %s' ), $item_details['value'] );
}
break;
default:
break;
}
}
if ( ! empty( $this->messages ) ) {
add_action( 'admin_notices', array( $this, 'render_php_compat_error' ) );
return false;
}
return true;
}
/**
* Renders the error messages as notice.
*/
public function render_php_compat_error() {
?>
<div class="notice notice-error">
<p>
<strong>
<?php printf( esc_html__( '%s error:' ), $this->checklist['plugin_name']['value'] ); ?>
</strong>
</p>
<?php if ( count( $this->messages ) > 1 ) : ?>
<ul>
<?php foreach ( $this->messages as $message ) : ?>
<li><?php echo esc_html( $message ); ?></li>
<?php endforeach; ?>
</ul>
<?php elseif ( 1 === count( $this->messages ) ): ?>
<p>
<?php echo esc_html( $this->messages[0] ); ?>
</p>
<?php endif; ?>
</div>
<?php
}
}

View File

@ -65,9 +65,9 @@ class Simple_Local_Avatars {
public function __construct() { public function __construct() {
$this->add_hooks(); $this->add_hooks();
$this->options = (array) get_option( 'simple_local_avatars' ); $this->options = (array) get_option( 'simple_local_avatars' );
$this->user_key = 'simple_local_avatar'; $this->user_key = 'simple_local_avatar';
$this->rating_key = 'simple_local_avatar_rating'; $this->rating_key = 'simple_local_avatar_rating';
if ( if (
! $this->is_avatar_shared() // Are we sharing avatars? ! $this->is_avatar_shared() // Are we sharing avatars?
@ -326,6 +326,20 @@ class Simple_Local_Avatars {
return $user_id; return $user_id;
} }
/**
* Get the local avatar user meta.
*
* @param int $user_id User ID.
* @return array Array with avatar data.
*/
public function get_user_local_avatar( $user_id ) {
$local_avatars = get_user_meta( $user_id, $this->user_key, true );
if ( ! is_array( $local_avatars ) || empty( $local_avatars ) ) {
return [];
}
return $local_avatars;
}
/** /**
* Get local avatar url. * Get local avatar url.
* *
@ -343,8 +357,8 @@ class Simple_Local_Avatars {
} }
// Fetch local avatar from meta and make sure it's properly set. // Fetch local avatar from meta and make sure it's properly set.
$local_avatars = get_user_meta( $user_id, $this->user_key, true ); $local_avatars = $this->get_user_local_avatar( $user_id );
if ( empty( $local_avatars['full'] ) ) { if ( ! isset( $local_avatars['full'] ) || empty( $local_avatars['full'] ) ) {
return ''; return '';
} }
@ -432,7 +446,7 @@ class Simple_Local_Avatars {
$dest_file_url = ''; $dest_file_url = '';
if ( false !== strpos( $dest_file, $upload_path['basedir'] ) ) { if ( false !== strpos( $dest_file, $upload_path['basedir'] ) ) {
$dest_file_url = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file ); $dest_file_url = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file );
} else if ( is_multisite() && false !== strpos( $dest_file, ABSPATH . 'wp-content/uploads' ) ) { } elseif ( is_multisite() && false !== strpos( $dest_file, ABSPATH . 'wp-content/uploads' ) ) {
$dest_file_url = str_replace( ABSPATH . 'wp-content/uploads', network_site_url( '/wp-content/uploads' ), $dest_file ); $dest_file_url = str_replace( ABSPATH . 'wp-content/uploads', network_site_url( '/wp-content/uploads' ), $dest_file );
} }
@ -479,8 +493,8 @@ class Simple_Local_Avatars {
} }
// Fetch local avatar from meta and make sure we have a media ID. // Fetch local avatar from meta and make sure we have a media ID.
$local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true ); $local_avatars = $this->get_user_local_avatar( $user_id );
if ( empty( $local_avatars['media_id'] ) ) { if ( ! isset( $local_avatars['media_id'] ) || empty( $local_avatars['media_id'] ) ) {
$alt = ''; $alt = '';
// If no avatar is set, check if we are using a default avatar with alt text. // If no avatar is set, check if we are using a default avatar with alt text.
if ( 'simple_local_avatar' === get_option( 'avatar_default' ) ) { if ( 'simple_local_avatar' === get_option( 'avatar_default' ) ) {
@ -557,13 +571,13 @@ class Simple_Local_Avatars {
*/ */
$this->avatar_ratings = array( $this->avatar_ratings = array(
/* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */ /* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */
'G' => __( 'G &#8212; Suitable for all audiences' ), 'G' => __( 'G &#8212; Suitable for all audiences', 'simple-local-avatars' ),
/* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */ /* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */
'PG' => __( 'PG &#8212; Possibly offensive, usually for audiences 13 and above' ), 'PG' => __( 'PG &#8212; Possibly offensive, usually for audiences 13 and above', 'simple-local-avatars' ),
/* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */ /* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */
'R' => __( 'R &#8212; Intended for adult audiences above 17' ), 'R' => __( 'R &#8212; Intended for adult audiences above 17', 'simple-local-avatars' ),
/* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */ /* translators: Content suitability rating: https://en.wikipedia.org/wiki/Motion_Picture_Association_of_America_film_rating_system */
'X' => __( 'X &#8212; Even more mature than above' ), 'X' => __( 'X &#8212; Even more mature than above', 'simple-local-avatars' ),
); );
} }
@ -702,7 +716,7 @@ class Simple_Local_Avatars {
$this->avatar_settings_field( $this->avatar_settings_field(
array( array(
'key' => 'only', 'key' => 'only',
'desc' => __( 'Only allow local avatars (still uses Gravatar for default avatars) ', 'simple-local-avatars' ), 'desc' => __( 'Only allow local avatars (still uses Gravatar for default avatars)', 'simple-local-avatars' ),
) )
); );
?> ?>
@ -950,7 +964,7 @@ class Simple_Local_Avatars {
if ( ! is_admin() || ! current_user_can( 'upload_files' ) ) { if ( ! is_admin() || ! current_user_can( 'upload_files' ) ) {
?> ?>
<p style="display: inline-block; width: 26em;"> <p style="display: inline-block; width: 26em;">
<span class="description"><?php esc_html_e( 'Choose an image from your computer:' ); ?></span><br /> <span class="description"><?php esc_html_e( 'Choose an image from your computer:', 'simple-local-avatars' ); ?></span><br />
<input type="file" name="simple-local-avatar" id="simple-local-avatar" class="standard-text" /> <input type="file" name="simple-local-avatar" id="simple-local-avatar" class="standard-text" />
</p> </p>
<?php } ?> <?php } ?>
@ -976,10 +990,10 @@ class Simple_Local_Avatars {
</td> </td>
</tr> </tr>
<tr class="ratings-row"> <tr class="ratings-row">
<th scope="row"><?php esc_html_e( 'Rating' ); ?></th> <th scope="row"><?php esc_html_e( 'Rating', 'simple-local-avatars' ); ?></th>
<td colspan="2"> <td colspan="2">
<fieldset id="simple-local-avatar-ratings" <?php disabled( empty( $profileuser->simple_local_avatar ) ); ?>> <fieldset id="simple-local-avatar-ratings" <?php disabled( empty( $profileuser->simple_local_avatar ) ); ?>>
<legend class="screen-reader-text"><span><?php esc_html_e( 'Rating' ); ?></span></legend> <legend class="screen-reader-text"><span><?php esc_html_e( 'Rating', 'simple-local-avatars' ); ?></span></legend>
<?php <?php
if ( empty( $profileuser->simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) ) { if ( empty( $profileuser->simple_local_avatar_rating ) || ! array_key_exists( $profileuser->simple_local_avatar_rating, $this->avatar_ratings ) ) {
$profileuser->simple_local_avatar_rating = 'G'; $profileuser->simple_local_avatar_rating = 'G';
@ -1035,7 +1049,7 @@ class Simple_Local_Avatars {
* *
* @param int $user_id Id of the user who's avatar was updated * @param int $user_id Id of the user who's avatar was updated
*/ */
do_action( 'simple_local_avatar_updated' , $user_id ); do_action( 'simple_local_avatar_updated', $user_id );
} }
/** /**
@ -1064,6 +1078,7 @@ class Simple_Local_Avatars {
$max_upload_size = $this->upload_size_limit( wp_max_upload_size() ); $max_upload_size = $this->upload_size_limit( wp_max_upload_size() );
if ( $_FILES['simple-local-avatar']['size'] > $max_upload_size ) { if ( $_FILES['simple-local-avatar']['size'] > $max_upload_size ) {
// translators: %s: Formatted size.
$this->avatar_upload_error = sprintf( __( 'Max allowed avatar size is %s', 'simple-local-avatars' ), size_format( $max_upload_size ) ); $this->avatar_upload_error = sprintf( __( 'Max allowed avatar size is %s', 'simple-local-avatars' ), size_format( $max_upload_size ) );
add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) ); add_action( 'user_profile_update_errors', array( $this, 'user_profile_update_errors' ) );
return; return;
@ -1110,7 +1125,7 @@ class Simple_Local_Avatars {
endif; endif;
// Handle ratings // Handle ratings
if ( isset( $avatar_id ) || get_user_meta( $user_id, $this->user_key, true ) ) { if ( isset( $avatar_id ) || ! empty( $this->get_user_local_avatar( $user_id ) ) ) {
if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) ) { if ( empty( $_POST['simple_local_avatar_rating'] ) || ! array_key_exists( $_POST['simple_local_avatar_rating'], $this->avatar_ratings ) ) {
$_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings ); $_POST['simple_local_avatar_rating'] = key( $this->avatar_ratings );
} }
@ -1180,7 +1195,7 @@ class Simple_Local_Avatars {
* @param int $user_id User ID. * @param int $user_id User ID.
*/ */
public function avatar_delete( $user_id ) { public function avatar_delete( $user_id ) {
$old_avatars = (array) get_user_meta( $user_id, $this->user_key, true ); $old_avatars = $this->get_user_local_avatar( $user_id );
if ( empty( $old_avatars ) ) { if ( empty( $old_avatars ) ) {
return; return;
@ -1191,10 +1206,20 @@ class Simple_Local_Avatars {
unset( $old_avatars['media_id'], $old_avatars['full'] ); unset( $old_avatars['media_id'], $old_avatars['full'] );
} }
// Remove the blog_id key as we don't need to try deleting a file based on that.
if ( array_key_exists( 'blog_id', $old_avatars ) ) {
unset( $old_avatars['blog_id'] );
}
if ( ! empty( $old_avatars ) ) { if ( ! empty( $old_avatars ) ) {
$upload_path = wp_upload_dir(); $upload_path = wp_upload_dir();
foreach ( $old_avatars as $old_avatar ) { foreach ( $old_avatars as $old_avatar ) {
// Ensure the avatar is in the uploads directory before we delete it.
if ( strpos( $old_avatar, $upload_path['baseurl'] ) !== 0 ) {
continue;
}
// derive the path for the file based on the upload directory // derive the path for the file based on the upload directory
$old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar ); $old_avatar_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $old_avatar );
if ( file_exists( $old_avatar_path ) ) { if ( file_exists( $old_avatar_path ) ) {
@ -1271,7 +1296,7 @@ class Simple_Local_Avatars {
* @param object $user User object * @param object $user User object
*/ */
public function get_avatar_rest( $user ) { public function get_avatar_rest( $user ) {
$local_avatar = get_user_meta( $user['id'], $this->user_key, true ); $local_avatar = $this->get_user_local_avatar( $user['id'] );
if ( empty( $local_avatar ) ) { if ( empty( $local_avatar ) ) {
return; return;
} }
@ -1288,9 +1313,34 @@ class Simple_Local_Avatars {
* *
* @param array $input Input submitted via REST request. * @param array $input Input submitted via REST request.
* @param object $user The user making the request. * @param object $user The user making the request.
* @return null|\WP_Error
*/ */
public function set_avatar_rest( $input, $user ) { public function set_avatar_rest( $input, $user ) {
$this->assign_new_user_avatar( $input['media_id'], $user->ID ); // Ensure media_id is set and is a number.
if (
empty( $input['media_id'] ) ||
! is_numeric( $input['media_id'] )
) {
return new \WP_Error( 'invalid_media_id', esc_html__( 'Request did not contain a valid media_id field.', 'simple-local-avatars' ) );
}
$attachment = get_post( (int) $input['media_id'] );
// Ensure this media_id is a valid attachment.
if (
! $attachment ||
'attachment' !== $attachment->post_type ||
! wp_attachment_is_image( $attachment )
) {
return new \WP_Error( 'invalid_media_id', esc_html__( 'Media ID did not match a valid attachment.', 'simple-local-avatars' ) );
}
// Ensure this attachment is associated with this user.
if ( (int) $attachment->post_author !== (int) $user->ID ) {
return new \WP_Error( 'invalid_media_id', esc_html__( 'This attachment was not uploaded by this user.', 'simple-local-avatars' ) );
}
$this->assign_new_user_avatar( (int) $input['media_id'], $user->ID );
} }
/** /**
@ -1373,6 +1423,13 @@ class Simple_Local_Avatars {
*/ */
public function sla_clear_user_cache() { public function sla_clear_user_cache() {
check_ajax_referer( 'sla_clear_cache_nonce', 'nonce' ); check_ajax_referer( 'sla_clear_cache_nonce', 'nonce' );
// Ensure this was run by a user with proper privileges.
if ( ! current_user_can( 'manage_options' ) ) {
// Match what `check_ajax_referer` does.
wp_die( -1, 403 );
}
$step = isset( $_REQUEST['step'] ) ? intval( $_REQUEST['step'] ) : 1; $step = isset( $_REQUEST['step'] ) ? intval( $_REQUEST['step'] ) : 1;
// Setup defaults. // Setup defaults.
@ -1396,7 +1453,7 @@ class Simple_Local_Avatars {
if ( ! empty( $users ) ) { if ( ! empty( $users ) ) {
foreach ( $users as $user ) { foreach ( $users as $user ) {
$user_id = $user->ID; $user_id = $user->ID;
$local_avatars = get_user_meta( $user_id, 'simple_local_avatar', true ); $local_avatars = $this->get_user_local_avatar( $user_id );
$media_id = isset( $local_avatars['media_id'] ) ? $local_avatars['media_id'] : ''; $media_id = isset( $local_avatars['media_id'] ) ? $local_avatars['media_id'] : '';
$this->clear_user_avatar_cache( $local_avatars, $user_id, $media_id ); $this->clear_user_avatar_cache( $local_avatars, $user_id, $media_id );
} }
@ -1442,9 +1499,9 @@ class Simple_Local_Avatars {
$file_name_data = pathinfo( get_attached_file( $media_id ) ); $file_name_data = pathinfo( get_attached_file( $media_id ) );
} }
$file_dir_name = $file_name_data['dirname']; $file_dir_name = $file_name_data['dirname'];
$file_name = $file_name_data['filename']; $file_name = $file_name_data['filename'];
$file_ext = $file_name_data['extension']; $file_ext = $file_name_data['extension'];
foreach ( $local_avatars as $local_avatars_key => $local_avatar_value ) { foreach ( $local_avatars as $local_avatars_key => $local_avatar_value ) {
if ( ! in_array( $local_avatars_key, [ 'media_id', 'full' ], true ) ) { if ( ! in_array( $local_avatars_key, [ 'media_id', 'full' ], true ) ) {
$file_size_path = sprintf( '%1$s/%2$s-%3$sx%3$s.%4$s', $file_dir_name, $file_name, $local_avatars_key, $file_ext ); $file_size_path = sprintf( '%1$s/%2$s-%3$sx%3$s.%4$s', $file_dir_name, $file_name, $local_avatars_key, $file_ext );
@ -1477,8 +1534,8 @@ class Simple_Local_Avatars {
<input type="hidden" name="simple-local-avatar-file-id" id="simple-local-avatar-file-id" value="<?php echo ! empty( $default_avatar_file_id ) ? esc_attr( $default_avatar_file_id ) : ''; ?>"/> <input type="hidden" name="simple-local-avatar-file-id" id="simple-local-avatar-file-id" value="<?php echo ! empty( $default_avatar_file_id ) ? esc_attr( $default_avatar_file_id ) : ''; ?>"/>
<input type="hidden" name="simple-local-avatar-file-url" id="simple-local-avatar-file-url" value="<?php echo ! empty( $default_avatar_file_url ) ? esc_url( $default_avatar_file_url ) : ''; ?>"/> <input type="hidden" name="simple-local-avatar-file-url" id="simple-local-avatar-file-url" value="<?php echo ! empty( $default_avatar_file_url ) ? esc_url( $default_avatar_file_url ) : ''; ?>"/>
<?php wp_nonce_field( 'simple_local_avatar_default', 'simple-local-avatar-file-wpnonce' ); ?> <?php wp_nonce_field( 'simple_local_avatar_default', 'simple-local-avatar-file-wpnonce' ); ?>
<input type="button" name="simple-local-avatar" id="simple-local-avatar-default" class="button-secondary" value="<?php esc_attr_e( 'Choose Default Avatar', 'simple-local-avatar' ); ?>"/> <input type="button" name="simple-local-avatar" id="simple-local-avatar-default" class="button-secondary" value="<?php esc_attr_e( 'Choose Default Avatar', 'simple-local-avatars' ); ?>"/>
<p class="description" style="margin-left: 23px;"><?php esc_html_e( 'Note that this avatar needs to be publicly available or a broken image will be shown.', 'simple-local-avatar' ); ?></p> <p class="description" style="margin-left: 23px;"><?php esc_html_e( 'Note that this avatar needs to be publicly available or a broken image will be shown.', 'simple-local-avatars' ); ?></p>
<?php <?php
$defaults['simple_local_avatar'] = ob_get_clean(); $defaults['simple_local_avatar'] = ob_get_clean();

View File

@ -2,8 +2,9 @@
Contributors: jakemgold, 10up, thinkoomph, jeffpaul, faisal03 Contributors: jakemgold, 10up, thinkoomph, jeffpaul, faisal03
Donate link: https://10up.com/plugins/simple-local-avatars-wordpress/ Donate link: https://10up.com/plugins/simple-local-avatars-wordpress/
Tags: avatar, gravatar, user photos, users, profile Tags: avatar, gravatar, user photos, users, profile
Tested up to: 6.6 Requires at least: 6.6
Stable tag: 2.7.11 Tested up to: 6.8
Stable tag: 2.8.3
License: GPL-2.0-or-later License: GPL-2.0-or-later
License URI: https://spdx.org/licenses/GPL-2.0-or-later.html License URI: https://spdx.org/licenses/GPL-2.0-or-later.html
@ -45,6 +46,33 @@ No. Simple Local Avatars neither collects, stores, nor sends any PII data of vi
== Changelog == == Changelog ==
= 2.8.3 - 2024-11-18 =
* **Changed:** Only allow images that were uploaded by the same user be used when setting the avatar via a REST request (props [@dkotter](https://github.com/dkotter), [@justus12337](https://github.com/justus12337), [@faisal-alvi](https://github.com/faisal-alvi) via [#317](https://github.com/10up/simple-local-avatars/pull/317)).
* **Fixed:** Only allow image files to be set as the avatar in REST requests (props [@dkotter](https://github.com/dkotter), [@justus12337](https://github.com/justus12337), [@faisal-alvi](https://github.com/faisal-alvi) via [#317](https://github.com/10up/simple-local-avatars/pull/317)).
* **Security:** Bump `@10up/cypress-wp-utils` from 0.2.0 to 0.4.0, `@sentry/node` from 6.19.7 to 8.38.0, `@wordpress/env` from 9.2.0 to 10.11.0, `cypress` from 13.2.0 to 13.15.2, `cypress-mochawesome-reporter` from 3.6.0 to 3.8.2, `puppeteer-core` from 23.3.0 to 23.8.0 (props [@dkotter](https://github.com/dkotter) via [#319](https://github.com/10up/simple-local-avatars/pull/319)).
= 2.8.2 - 2024-11-12 =
* **Fixed:** Ensure dependencies are (actually) included properly in the release (props [@dkotter](https://github.com/dkotter) via [#316](https://github.com/10up/simple-local-avatars/pull/316)).
= 2.8.1 - 2024-11-12 =
* **Fixed:** Ensure dependencies are included properly in the release (props [@dkotter](https://github.com/dkotter) via [#315](https://github.com/10up/simple-local-avatars/pull/315)).
= 2.8.0 - 2024-11-12 =
**Note that this release bumps the minimum required version of WordPress from 6.4 to 6.5.**
* **Added:** Support for the WordPress.org plugin preview (props [@faisal-alvi](https://github.com/faisal-alvi), [@jeffpaul](https://github.com/jeffpaul) via [#297](https://github.com/10up/simple-local-avatars/pull/297)).
* **Changed:** Update PHP compatibility check to use `10up/wp-compat-validation-tool` (props [@Sidsector9](https://github.com/Sidsector9), [@jeffpaul](https://github.com/jeffpaul), [@faisal-alvi](https://github.com/faisal-alvi) via [#291](https://github.com/10up/simple-local-avatars/pull/291)).
* **Changed:** Bump Wordpress "tested up to" version 6.7 (props [@sudip-md](https://github.com/sudip-md), [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter) via [#310](https://github.com/10up/simple-local-avatars/pull/310), [#312](https://github.com/10up/simple-local-avatars/pull/312)).
* **Changed:** Bump WordPress minimum supported version to 6.5 (props [@sudip-md](https://github.com/sudip-md), [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter) via [#310](https://github.com/10up/simple-local-avatars/pull/310), [#312](https://github.com/10up/simple-local-avatars/pull/312)).
* **Fixed:** Ensure all strings are properly translated (props [@pedro-mendonca](https://github.com/pedro-mendonca), [@dkotter](https://github.com/dkotter) via [#295](https://github.com/10up/simple-local-avatars/pull/295)).
* **Fixed:** Properly handle malformed `simple_local_avatar` user data (props [@adekbadek](https://github.com/adekbadek), [@dkotter](https://github.com/dkotter), [@faisal-alvi](https://github.com/faisal-alvi) via [#302](https://github.com/10up/simple-local-avatars/pull/302)).
* **Security:** Run a user capability check before we clear the avatar cache (props [@dkotter](https://github.com/dkotter), [@truonghuuphuc](https://github.com/truonghuuphuc), [@Sidsector9](https://github.com/Sidsector9) via [#309](https://github.com/10up/simple-local-avatars/pull/309)).
* **Security:** Ensure REST API requests to set an avatar only allow existing attachment IDs to be used (props [@dkotter](https://github.com/dkotter), [@justus12337](https://github.com/justus12337), [@faisal-alvi](https://github.com/faisal-alvi) via [GHSA-wfjh-m788-w2c5](https://github.com/10up/simple-local-avatars/security/advisories/GHSA-wfjh-m788-w2c5)).
* **Security:** Bump `axios` from 1.6.7 to 1.7.4 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#298](https://github.com/10up/simple-local-avatars/pull/298)).
* **Security:** Bump `webpack` from 5.90.0 to 5.94.0 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#303](https://github.com/10up/simple-local-avatars/pull/303)).
* **Security:** Bump `ws` from 7.5.10 to 8.18.0 and `@wordpress/scripts` from 27.1.0 to 30.4.0 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#305](https://github.com/10up/simple-local-avatars/pull/305), [#311](https://github.com/10up/simple-local-avatars/pull/311)).
* **Security:** Bump `body-parser` from 1.20.2 to 1.20.3, `express` from 4.19.2 to 4.21.0, `send` from 0.18.0 to 0.19.0 and `serve-static` from 1.15.0 to 1.16.2 (props [@dependabot](https://github.com/apps/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#306](https://github.com/10up/simple-local-avatars/pull/306)).
= 2.7.11 - 2024-07-18 = = 2.7.11 - 2024-07-18 =
**Note that this release bumps the minimum required version of WordPress from 6.3 to 6.4.** **Note that this release bumps the minimum required version of WordPress from 6.3 to 6.4.**
@ -104,51 +132,13 @@ No. Simple Local Avatars neither collects, stores, nor sends any PII data of vi
* **Security:** Bump `@wordpress/env` version from 5.2.0 to 8.7.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)). * **Security:** Bump `@wordpress/env` version from 5.2.0 to 8.7.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)).
* **Security:** Bump `cypress-mochawesome-reporter` version from 3.0.1 to 3.6.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)). * **Security:** Bump `cypress-mochawesome-reporter` version from 3.0.1 to 3.6.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#236](https://github.com/10up/simple-local-avatars/pull/236)).
= 2.7.5 - 2023-05-15 =
* **Added:** Ajax loading animation during process of uploading and deleting local avatars (props [@lllopo](https://github.com/lllopo), [@BhargavBhandari90](https://github.com/BhargavBhandari90), [@faisal-alvi](https://github.com/faisal-alvi) via [#204](https://github.com/10up/simple-local-avatars/pull/204)).
* **Changed:** Avatar removal button text (props [@jayedul](https://github.com/jayedul), [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter), [@faisal-alvi](https://github.com/faisal-alvi) via [#208](https://github.com/10up/simple-local-avatars/pull/208)).
* **Changed:** WordPress "tested up to" version 6.2 (props [@jayedul](https://github.com/jayedul), [@faisal-alvi](https://github.com/faisal-alvi) via [#210](https://github.com/10up/simple-local-avatars/pull/210)).
* **Changed:** Run E2E tests on the zip generated by "Build release zip" action (props [@jayedul](https://github.com/jayedul), [@iamdharmesh](https://github.com/iamdharmesh), [@faisal-alvi](https://github.com/faisal-alvi) via [#205](https://github.com/10up/simple-local-avatars/pull/205)).
* **Security:** Bump `webpack` from 5.75.0 to 5.76.1 (props [@dependabot](https://github.com/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#207](https://github.com/10up/simple-local-avatars/pull/207)).
= 2.7.4 - 2023-02-23 =
* **Fixed:** Support passing `WP_User` to `get_avatar()` (props [@mattheu](https://github.com/mattheu), [@faisal-alvi](https://github.com/faisal-alvi) via [#193](https://github.com/10up/simple-local-avatars/pull/193)).
* **Fixed:** Remove trailing commas in function calls (props [@patrixer](https://github.com/patrixer), [@dkotter](https://github.com/dkotter), [@sekra24](https://github.com/sekra24), [@faisal-alvi](https://github.com/faisal-alvi) via [#196](https://github.com/10up/simple-local-avatars/pull/196)).
* **Security:** Bump `simple-git` from 3.15.1 to 3.16.0 (props [@dependabot](https://github.com/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#191](https://github.com/10up/simple-local-avatars/pull/191)).
* **Security:** Bump `http-cache-semantics` from 4.1.0 to 4.1.1 (props [@dependabot](https://github.com/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#197](https://github.com/10up/simple-local-avatars/pull/197)).
= 2.7.3 - 2023-01-16 =
* **Fixed:** Issue causing fatal errors when avatars used on front end of site (props [@Rottinator](https://github.com/Rottinator), [@peterwilsoncc](https://github.com/peterwilsoncc), [@ravinderk](https://github.com/ravinderk), [@faisal-alvi](https://github.com/faisal-alvi) via [#187](https://github.com/10up/simple-local-avatars/pull/187)).
* **Fixed:** Deprecation error in admin on PHP 8.0 and later (props [@Rottinator](https://github.com/Rottinator), [@peterwilsoncc](https://github.com/peterwilsoncc), [@ravinderk](https://github.com/ravinderk), [@faisal-alvi](https://github.com/faisal-alvi) via [#187](https://github.com/10up/simple-local-avatars/pull/187)).
= 2.7.2 - 2023-01-13 =
* **Added:** Filter hook `simple_local_avatars_upload_limit` to restrict image upload size & image file checking enhanced (props [@Shirkit](https://github.com/Shirkit), [@jayedul](https://github.com/jayedul), [@faisal-alvi](https://github.com/faisal-alvi), [@jeffpaul](https://github.com/jeffpaul) via [#171](https://github.com/10up/simple-local-avatars/pull/171)).
* **Added:** GitHub Actions summary on Cypress e2e test runs (props [@faisal-alvi](https://github.com/faisal-alvi), [@jeffpaul](https://github.com/jeffpaul), [@iamdharmesh](https://github.com/iamdharmesh) via [#174](https://github.com/10up/simple-local-avatars/pull/174)).
* **Changed:** Cypress integration migrated from 9.5.4 to 11.2.0 (props [@iamdharmesh](https://github.com/iamdharmesh), [@jayedul](https://github.com/jayedul), [@faisal-alvi](https://github.com/faisal-alvi) via [#172](https://github.com/10up/simple-local-avatars/pull/172)).
* **Fixed:** PHP8 support for `assign_new_user_avatar` (props [@lllopo](https://github.com/lllopo), [@mattwatsoncodes](https://github.com/mattwatsoncodes), [@faisal-alvi](https://github.com/faisal-alvi) via [#183](https://github.com/10up/simple-local-avatars/pull/183)).
* **Fixed:** Fixed the user profile language not respected issue (props [@dkotter](https://github.com/dkotter), [@lllopo](https://github.com/lllopo), [@faisal-alvi](https://github.com/faisal-alvi), [@jeffpaul](https://github.com/jeffpaul) via [#175](https://github.com/10up/simple-local-avatars/pull/175)).
* **Removed:** textdomain from the core strings and the function `update_avatar_ratings` as it's not required anymore (props [@dkotter](https://github.com/dkotter), [@lllopo](https://github.com/lllopo), [@faisal-alvi](https://github.com/faisal-alvi), [@jeffpaul](https://github.com/jeffpaul) via [#175](https://github.com/10up/simple-local-avatars/pull/175)).
* **Security:** Bump `json5` from 1.0.1 to 1.0.2 (props [@dependabot](https://github.com/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#182](https://github.com/10up/simple-local-avatars/pull/182)).
= 2.7.1 - 2022-12-08 =
* **Added:** Added missing files from the last release and changed the readme file to fix the bullet points and added fullstops.
= 2.7.0 - 2022-12-08 =
* **Added:** Added `Build release zip` GitHub Action (props [@peterwilsoncc](https://github.com/peterwilsoncc), [@faisal-alvi](https://github.com/faisal-alvi) via [#168](https://github.com/10up/simple-local-avatars/pull/168)).
* **Changed:** Set plugin defaults on `wp_initialize_site` instead of deprecated action `wpmu_new_blog` (props [@kadamwhite](https://github.com/kadamwhite), [@faisal-alvi](https://github.com/faisal-alvi) via [#156](https://github.com/10up/simple-local-avatars/pull/156)).
* **Changed:** Support Level from Active to Stable (props [@jeffpaul](https://github.com/jeffpaul), [@dkotter](https://github.com/dkotter) via [#159](https://github.com/10up/simple-local-avatars/pull/159)).
* **Changed:** Build tools: Allow PHPCS installer plugin to run without prompting user (props [@peterwilsoncc](https://github.com/peterwilsoncc), [@jeffpaul](https://github.com/jeffpaul) via [#164](https://github.com/10up/simple-local-avatars/pull/164)).
* **Changed:** WP tested up to version bump to 6.1 (props [@peterwilsoncc](https://github.com/peterwilsoncc), [@faisal-alvi](https://github.com/faisal-alvi) via [#165](https://github.com/10up/simple-local-avatars/pull/165)).
* **Fixed:** Non admin users can not crop avatar (props [@jayedul](https://github.com/jayedul), [@faisal-alvi](https://github.com/faisal-alvi), [@zamanq](https://github.com/zamanq), [@dkotter](https://github.com/dkotter), [@jeffpaul](https://github.com/jeffpaul) via [#155](https://github.com/10up/simple-local-avatars/pull/155)).
* **Security:** Bump `@wordpress/env` from 4.9.0 to 5.2.0 and `got` from 10.7.0 to 11.8.5 (props [@dependabot](https://github.com/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#153](https://github.com/10up/simple-local-avatars/pull/153)).
* **Security:** Bump `loader-utils` from 2.0.2 to 2.0.3 (props [@dependabot](https://github.com/dependabot), [@faisal-alvi](https://github.com/faisal-alvi) via [#160](https://github.com/10up/simple-local-avatars/pull/160)).
* **Security:** Bump `loader-utils` from 2.0.3 to 2.0.4 (props [@dependabot](https://github.com/dependabot), [@peterwilsoncc](https://github.com/peterwilsoncc) via [#162](https://github.com/10up/simple-local-avatars/pull/162)).
* **Security:** Bump `simple-git` from 3.9.0 to 3.15.1 (props [@dependabot](https://github.com/dependabot) via [#176](https://github.com/10up/simple-local-avatars/pull/176)).
[View historical changelog details here](https://github.com/10up/simple-local-avatars/blob/develop/CHANGELOG.md). [View historical changelog details here](https://github.com/10up/simple-local-avatars/blob/develop/CHANGELOG.md).
== Upgrade Notice == == Upgrade Notice ==
= 2.8.0 =
**Note that this release bumps the minimum required version of WordPress from 6.4 to 6.5.**
= 2.7.11 = = 2.7.11 =
**Note that this release bumps the minimum required version of WordPress from 6.3 to 6.4.** **Note that this release bumps the minimum required version of WordPress from 6.3 to 6.4.**

View File

@ -3,8 +3,8 @@
* Plugin Name: Simple Local Avatars * Plugin Name: Simple Local Avatars
* Plugin URI: https://10up.com/plugins/simple-local-avatars-wordpress/ * Plugin URI: https://10up.com/plugins/simple-local-avatars-wordpress/
* Description: Adds an avatar upload field to user profiles. Generates requested sizes on demand, just like Gravatar! Simple and lightweight. * Description: Adds an avatar upload field to user profiles. Generates requested sizes on demand, just like Gravatar! Simple and lightweight.
* Version: 2.7.11 * Version: 2.8.3
* Requires at least: 6.4 * Requires at least: 6.5
* Requires PHP: 7.4 * Requires PHP: 7.4
* Author: 10up * Author: 10up
* Author URI: https://10up.com * Author URI: https://10up.com
@ -15,50 +15,18 @@
* @package SimpleLocalAvatars * @package SimpleLocalAvatars
*/ */
/** if ( ! is_readable( __DIR__ . '/10up-lib/wp-compat-validation-tool/src/Validator.php' ) ) {
* Get the minimum version of PHP required by this plugin. return;
*
* @since 2.7.6
*
* @return string Minimum version required.
*/
function minimum_php_requirement() {
return '7.4';
} }
/** require_once '10up-lib/wp-compat-validation-tool/src/Validator.php';
* Whether PHP installation meets the minimum requirements
*
* @since 2.7.6
*
* @return bool True if meets minimum requirements, false otherwise.
*/
function site_meets_php_requirements() {
return version_compare( phpversion(), minimum_php_requirement(), '>=' );
}
// Try to load the plugin files, ensuring our PHP version is met first. $compat_checker = new \SimpleLocalAvatarsValidator\Validator();
if ( ! site_meets_php_requirements() ) { $compat_checker
add_action( ->set_plugin_name( 'Simple Local Avatars' )
'admin_notices', ->set_php_min_required_version( '7.4' );
function() {
?> if ( ! $compat_checker->is_plugin_compatible() ) {
<div class="notice notice-error">
<p>
<?php
echo wp_kses_post(
sprintf(
/* translators: %s: Minimum required PHP version */
__( 'Simple Local Avatars requires PHP version %s or later. Please upgrade PHP or disable the plugin.', 'simple-local-avatars' ),
esc_html( minimum_php_requirement() )
)
);
?>
</p>
</div>
<?php
}
);
return; return;
} }
@ -67,7 +35,7 @@ define( 'SLA_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
require_once dirname( __FILE__ ) . '/includes/class-simple-local-avatars.php'; require_once dirname( __FILE__ ) . '/includes/class-simple-local-avatars.php';
// Global constants. // Global constants.
define( 'SLA_VERSION', '2.7.11' ); define( 'SLA_VERSION', '2.8.3' );
define( 'SLA_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); define( 'SLA_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
if ( ! defined( 'SLA_IS_NETWORK' ) ) { if ( ! defined( 'SLA_IS_NETWORK' ) ) {
@ -106,7 +74,7 @@ function simple_local_avatars_uninstall() {
$simple_local_avatars = new Simple_Local_Avatars(); $simple_local_avatars = new Simple_Local_Avatars();
$users = get_users( $users = get_users(
array( array(
'meta_key' => 'simple_local_avatar', 'meta_key' => 'simple_local_avatar', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'fields' => 'ids', 'fields' => 'ids',
) )
); );

View File

@ -0,0 +1,25 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit998b6fd9c25857a5c183b81c7706d47e::getLoader();

View File

@ -0,0 +1,579 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@ -0,0 +1,359 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed;
}
}

View File

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,10 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
);

View File

@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -0,0 +1,11 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'WP_Compat_Validation_Tool\\' => array($baseDir . '/10up-lib/wp-compat-validation-tool/src'),
'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
);

View File

@ -0,0 +1,38 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit998b6fd9c25857a5c183b81c7706d47e
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit998b6fd9c25857a5c183b81c7706d47e', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit998b6fd9c25857a5c183b81c7706d47e', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit998b6fd9c25857a5c183b81c7706d47e::getInitializer($loader));
$loader->register(true);
return $loader;
}
}

View File

@ -0,0 +1,44 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit998b6fd9c25857a5c183b81c7706d47e
{
public static $prefixLengthsPsr4 = array (
'W' =>
array (
'WP_Compat_Validation_Tool\\' => 26,
),
'C' =>
array (
'Composer\\Installers\\' => 20,
),
);
public static $prefixDirsPsr4 = array (
'WP_Compat_Validation_Tool\\' =>
array (
0 => __DIR__ . '/../..' . '/10up-lib/wp-compat-validation-tool/src',
),
'Composer\\Installers\\' =>
array (
0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
),
);
public static $classMap = array (
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit998b6fd9c25857a5c183b81c7706d47e::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit998b6fd9c25857a5c183b81c7706d47e::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit998b6fd9c25857a5c183b81c7706d47e::$classMap;
}, null, ClassLoader::class);
}
}

View File

@ -0,0 +1,194 @@
{
"packages": [
{
"name": "10up/wp-compat-validation-tool",
"version": "dev-trunk",
"version_normalized": "dev-trunk",
"source": {
"type": "git",
"url": "https://github.com/10up/wp-compat-validation-tool.git",
"reference": "19a8c7c1d39d3a4c896aeeac8d42edd20b8d2317"
},
"require": {
"composer/installers": "^2.2"
},
"time": "2023-11-09T18:48:23+00:00",
"type": "wordpress-plugin",
"extra": {
"installer-name": "10up-lib/wp-compat-validation-tool"
},
"installation-source": "source",
"autoload": {
"psr-4": {
"WP_Compat_Validation_Tool\\": "src/"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "10up",
"email": "opensource@10up.com",
"homepage": "https://10up.com",
"role": "Developer"
}
],
"description": "Perform PHP and WP version compatibility checks in your plugin.",
"homepage": "https://github.com/10up/wp-compat-validation-tool",
"install-path": "../../10up-lib/wp-compat-validation-tool"
},
{
"name": "composer/installers",
"version": "dev-main",
"version_normalized": "dev-main",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
"reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/12fb2dfe5e16183de69e784a7b84046c43d97e8e",
"reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0",
"php": "^7.2 || ^8.0"
},
"require-dev": {
"composer/composer": "^1.10.27 || ^2.7",
"composer/semver": "^1.7.2 || ^3.4.0",
"phpstan/phpstan": "^1.11",
"phpstan/phpstan-phpunit": "^1",
"symfony/phpunit-bridge": "^7.1.1",
"symfony/process": "^5 || ^6 || ^7"
},
"time": "2024-06-24T20:46:46+00:00",
"default-branch": true,
"type": "composer-plugin",
"extra": {
"class": "Composer\\Installers\\Plugin",
"branch-alias": {
"dev-main": "2.x-dev"
},
"plugin-modifies-install-path": true
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Composer\\Installers\\": "src/Composer/Installers"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Kyle Robinson Young",
"email": "kyle@dontkry.com",
"homepage": "https://github.com/shama"
}
],
"description": "A multi-framework Composer library installer",
"homepage": "https://composer.github.io/installers/",
"keywords": [
"Dolibarr",
"Eliasis",
"Hurad",
"ImageCMS",
"Kanboard",
"Lan Management System",
"MODX Evo",
"MantisBT",
"Mautic",
"Maya",
"OXID",
"Plentymarkets",
"Porto",
"RadPHP",
"SMF",
"Starbug",
"Thelia",
"Whmcs",
"WolfCMS",
"agl",
"annotatecms",
"attogram",
"bitrix",
"cakephp",
"chef",
"cockpit",
"codeigniter",
"concrete5",
"concreteCMS",
"croogo",
"dokuwiki",
"drupal",
"eZ Platform",
"elgg",
"expressionengine",
"fuelphp",
"grav",
"installer",
"itop",
"known",
"kohana",
"laravel",
"lavalite",
"lithium",
"magento",
"majima",
"mako",
"matomo",
"mediawiki",
"miaoxing",
"modulework",
"modx",
"moodle",
"osclass",
"pantheon",
"phpbb",
"piwik",
"ppi",
"processwire",
"puppet",
"pxcms",
"reindex",
"roundcube",
"shopware",
"silverstripe",
"sydes",
"sylius",
"tastyigniter",
"wordpress",
"yawik",
"zend",
"zikula"
],
"support": {
"issues": "https://github.com/composer/installers/issues",
"source": "https://github.com/composer/installers/tree/v2.3.0"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"install-path": "./installers"
}
],
"dev": false,
"dev-package-names": []
}

View File

@ -0,0 +1,43 @@
<?php return array(
'root' => array(
'name' => '10up/simple-local-avatars',
'pretty_version' => '2.8.3',
'version' => '2.8.3.0',
'reference' => 'f30aabcce169c2325759a8e9754e8ac82d948396',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'10up/simple-local-avatars' => array(
'pretty_version' => '2.8.3',
'version' => '2.8.3.0',
'reference' => 'f30aabcce169c2325759a8e9754e8ac82d948396',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'10up/wp-compat-validation-tool' => array(
'pretty_version' => 'dev-trunk',
'version' => 'dev-trunk',
'reference' => '19a8c7c1d39d3a4c896aeeac8d42edd20b8d2317',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../10up-lib/wp-compat-validation-tool',
'aliases' => array(),
'dev_requirement' => false,
),
'composer/installers' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => '12fb2dfe5e16183de69e784a7b84046c43d97e8e',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/./installers',
'aliases' => array(
0 => '2.x-dev',
),
'dev_requirement' => false,
),
),
);

View File

@ -0,0 +1,65 @@
name: "Continuous Integration"
on:
- push
- pull_request
env:
COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist"
SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT: "1"
permissions:
contents: read
jobs:
tests:
name: "CI"
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
- "7.2"
- "7.3"
- "7.4"
- "8.0"
- "8.1"
dependencies: [locked]
include:
- php-version: "7.2"
dependencies: lowest
- php-version: "8.1"
dependencies: lowest
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: composer:snapshot
- name: Get composer cache directory
id: composercache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composercache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: "Handle lowest dependencies update"
if: "contains(matrix.dependencies, 'lowest')"
run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV"
- name: "Install latest dependencies"
run: "composer update ${{ env.COMPOSER_FLAGS }}"
- name: "Run tests"
run: "vendor/bin/simple-phpunit --verbose"

View File

@ -0,0 +1,33 @@
name: "PHP Lint"
on:
- push
- pull_request
permissions:
contents: read
jobs:
tests:
name: "Lint"
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
- "7.2"
- "latest"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
- name: "Lint PHP files"
run: "find src/ -type f -name '*.php' -print0 | xargs -0 -L1 -P4 -- php -l -f"

View File

@ -0,0 +1,52 @@
name: "PHPStan"
on:
- push
- pull_request
env:
COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist"
SYMFONY_PHPUNIT_VERSION: ""
permissions:
contents: read
jobs:
tests:
name: "PHPStan"
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
- "8.0"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
- name: Get composer cache directory
id: composercache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composercache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
- name: "Install latest dependencies"
run: "composer update ${{ env.COMPOSER_FLAGS }}"
- name: Run PHPStan
run: |
composer require --dev phpunit/phpunit:^8.5.18 --with-all-dependencies ${{ env.COMPOSER_FLAGS }}
vendor/bin/phpstan analyse

View File

@ -0,0 +1,19 @@
Copyright (c) 2012 Kyle Robinson Young
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,117 @@
{
"name": "composer/installers",
"type": "composer-plugin",
"license": "MIT",
"description": "A multi-framework Composer library installer",
"keywords": [
"installer",
"AGL",
"AnnotateCms",
"Attogram",
"Bitrix",
"CakePHP",
"Chef",
"Cockpit",
"CodeIgniter",
"concrete5",
"ConcreteCMS",
"Croogo",
"DokuWiki",
"Dolibarr",
"Drupal",
"Elgg",
"Eliasis",
"ExpressionEngine",
"eZ Platform",
"FuelPHP",
"Grav",
"Hurad",
"ImageCMS",
"iTop",
"Kanboard",
"Known",
"Kohana",
"Lan Management System",
"Laravel",
"Lavalite",
"Lithium",
"Magento",
"majima",
"Mako",
"MantisBT",
"Matomo",
"Mautic",
"Maya",
"MODX",
"MODX Evo",
"MediaWiki",
"Miaoxing",
"OXID",
"osclass",
"MODULEWork",
"Moodle",
"Pantheon",
"Piwik",
"pxcms",
"phpBB",
"Plentymarkets",
"PPI",
"Puppet",
"Porto",
"ProcessWire",
"RadPHP",
"ReIndex",
"Roundcube",
"shopware",
"SilverStripe",
"SMF",
"Starbug",
"SyDES",
"Sylius",
"TastyIgniter",
"Thelia",
"WHMCS",
"WolfCMS",
"WordPress",
"YAWIK",
"Zend",
"Zikula"
],
"homepage": "https://composer.github.io/installers/",
"authors": [
{
"name": "Kyle Robinson Young",
"email": "kyle@dontkry.com",
"homepage": "https://github.com/shama"
}
],
"autoload": {
"psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
},
"autoload-dev": {
"psr-4": { "Composer\\Installers\\Test\\": "tests/Composer/Installers/Test" }
},
"extra": {
"class": "Composer\\Installers\\Plugin",
"branch-alias": {
"dev-main": "2.x-dev"
},
"plugin-modifies-install-path": true
},
"require": {
"php": "^7.2 || ^8.0",
"composer-plugin-api": "^1.0 || ^2.0"
},
"require-dev": {
"composer/composer": "^1.10.27 || ^2.7",
"composer/semver": "^1.7.2 || ^3.4.0",
"symfony/phpunit-bridge": "^7.1.1",
"phpstan/phpstan": "^1.11",
"symfony/process": "^5 || ^6 || ^7",
"phpstan/phpstan-phpunit": "^1"
},
"scripts": {
"test": "@php vendor/bin/simple-phpunit",
"phpstan": "@php vendor/bin/phpstan analyse"
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Composer\Installers;
class AglInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'More/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$name = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
return strtoupper($matches[1]);
}, $vars['name']);
if (null === $name) {
throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error());
}
$vars['name'] = $name;
return $vars;
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Composer\Installers;
class AkauntingInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class AnnotateCmsInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'addons/modules/{$name}/',
'component' => 'addons/components/{$name}/',
'service' => 'addons/services/{$name}/',
);
}

View File

@ -0,0 +1,58 @@
<?php
namespace Composer\Installers;
class AsgardInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'Modules/{$name}/',
'theme' => 'Themes/{$name}/'
);
/**
* Format package name.
*
* For package type asgard-module, cut off a trailing '-plugin' if present.
*
* For package type asgard-theme, cut off a trailing '-theme' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'asgard-module') {
return $this->inflectPluginVars($vars);
}
if ($vars['type'] === 'asgard-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectPluginVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectThemeVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class AttogramInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,137 @@
<?php
namespace Composer\Installers;
use Composer\IO\IOInterface;
use Composer\Composer;
use Composer\Package\PackageInterface;
abstract class BaseInstaller
{
/** @var array<string, string> */
protected $locations = array();
/** @var Composer */
protected $composer;
/** @var PackageInterface */
protected $package;
/** @var IOInterface */
protected $io;
/**
* Initializes base installer.
*/
public function __construct(PackageInterface $package, Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->package = $package;
$this->io = $io;
}
/**
* Return the install path based on package type.
*/
public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string
{
$type = $this->package->getType();
$prettyName = $this->package->getPrettyName();
if (strpos($prettyName, '/') !== false) {
list($vendor, $name) = explode('/', $prettyName);
} else {
$vendor = '';
$name = $prettyName;
}
$availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
$extra = $package->getExtra();
if (!empty($extra['installer-name'])) {
$availableVars['name'] = $extra['installer-name'];
}
$extra = $this->composer->getPackage()->getExtra();
if (!empty($extra['installer-paths'])) {
$customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
if ($customPath !== false) {
return $this->templatePath($customPath, $availableVars);
}
}
$packageType = substr($type, strlen($frameworkType) + 1);
$locations = $this->getLocations($frameworkType);
if (!isset($locations[$packageType])) {
throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
}
return $this->templatePath($locations[$packageType], $availableVars);
}
/**
* For an installer to override to modify the vars per installer.
*
* @param array<string, string> $vars This will normally receive array{name: string, vendor: string, type: string}
* @return array<string, string>
*/
public function inflectPackageVars(array $vars): array
{
return $vars;
}
/**
* Gets the installer's locations
*
* @return array<string, string> map of package types => install path
*/
public function getLocations(string $frameworkType)
{
return $this->locations;
}
/**
* Replace vars in a path
*
* @param array<string, string> $vars
*/
protected function templatePath(string $path, array $vars = array()): string
{
if (strpos($path, '{') !== false) {
extract($vars);
preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $var) {
$path = str_replace('{$' . $var . '}', $$var, $path);
}
}
}
return $path;
}
/**
* Search through a passed paths array for a custom install path.
*
* @param array<string, string[]|string> $paths
* @return string|false
*/
protected function mapCustomInstallPaths(array $paths, string $name, string $type, ?string $vendor = null)
{
foreach ($paths as $path => $names) {
$names = (array) $names;
if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
return $path;
}
}
return false;
}
protected function pregReplace(string $pattern, string $replacement, string $subject): string
{
$result = preg_replace($pattern, $replacement, $subject);
if (null === $result) {
throw new \RuntimeException('Failed to run preg_replace with '.$pattern.': '.preg_last_error());
}
return $result;
}
}

View File

@ -0,0 +1,123 @@
<?php
namespace Composer\Installers;
use Composer\Util\Filesystem;
/**
* Installer for Bitrix Framework. Supported types of extensions:
* - `bitrix-d7-module` copy the module to directory `bitrix/modules/<vendor>.<name>`.
* - `bitrix-d7-component` copy the component to directory `bitrix/components/<vendor>/<name>`.
* - `bitrix-d7-template` copy the template to directory `bitrix/templates/<vendor>_<name>`.
*
* You can set custom path to directory with Bitrix kernel in `composer.json`:
*
* ```json
* {
* "extra": {
* "bitrix-dir": "s1/bitrix"
* }
* }
* ```
*
* @author Nik Samokhvalov <nik@samokhvalov.info>
* @author Denis Kulichkin <onexhovia@gmail.com>
*/
class BitrixInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
);
/**
* @var string[] Storage for informations about duplicates at all the time of installation packages.
*/
private static $checkedDuplicates = array();
public function inflectPackageVars(array $vars): array
{
/** @phpstan-ignore-next-line */
if ($this->composer->getPackage()) {
$extra = $this->composer->getPackage()->getExtra();
if (isset($extra['bitrix-dir'])) {
$vars['bitrix_dir'] = $extra['bitrix-dir'];
}
}
if (!isset($vars['bitrix_dir'])) {
$vars['bitrix_dir'] = 'bitrix';
}
return parent::inflectPackageVars($vars);
}
/**
* {@inheritdoc}
*/
protected function templatePath(string $path, array $vars = array()): string
{
$templatePath = parent::templatePath($path, $vars);
$this->checkDuplicates($templatePath, $vars);
return $templatePath;
}
/**
* Duplicates search packages.
*
* @param array<string, string> $vars
*/
protected function checkDuplicates(string $path, array $vars = array()): void
{
$packageType = substr($vars['type'], strlen('bitrix') + 1);
$localDir = explode('/', $vars['bitrix_dir']);
array_pop($localDir);
$localDir[] = 'local';
$localDir = implode('/', $localDir);
$oldPath = str_replace(
array('{$bitrix_dir}', '{$name}'),
array($localDir, $vars['name']),
$this->locations[$packageType]
);
if (in_array($oldPath, static::$checkedDuplicates)) {
return;
}
if ($oldPath !== $path && file_exists($oldPath) && $this->io->isInteractive()) {
$this->io->writeError(' <error>Duplication of packages:</error>');
$this->io->writeError(' <info>Package ' . $oldPath . ' will be called instead package ' . $path . '</info>');
while (true) {
switch ($this->io->ask(' <info>Delete ' . $oldPath . ' [y,n,?]?</info> ', '?')) {
case 'y':
$fs = new Filesystem();
$fs->removeDirectory($oldPath);
break 2;
case 'n':
break 2;
case '?':
default:
$this->io->writeError(array(
' y - delete package ' . $oldPath . ' and to continue with the installation',
' n - don\'t delete and to continue with the installation',
));
$this->io->writeError(' ? - print help');
break;
}
}
}
static::$checkedDuplicates[] = $oldPath;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class BonefishInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'package' => 'Packages/{$vendor}/{$name}/'
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class BotbleInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'platform/plugins/{$name}/',
'theme' => 'platform/themes/{$name}/',
);
}

View File

@ -0,0 +1,67 @@
<?php
namespace Composer\Installers;
use Composer\DependencyResolver\Pool;
use Composer\Semver\Constraint\Constraint;
class CakePHPInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'Plugin/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
if ($this->matchesCakeVersion('>=', '3.0.0')) {
return $vars;
}
$nameParts = explode('/', $vars['name']);
foreach ($nameParts as &$value) {
$value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value));
$value = str_replace(array('-', '_'), ' ', $value);
$value = str_replace(' ', '', ucwords($value));
}
$vars['name'] = implode('/', $nameParts);
return $vars;
}
/**
* Change the default plugin location when cakephp >= 3.0
*/
public function getLocations(string $frameworkType): array
{
if ($this->matchesCakeVersion('>=', '3.0.0')) {
$this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
}
return $this->locations;
}
/**
* Check if CakePHP version matches against a version
*
* @phpstan-param '='|'=='|'<'|'<='|'>'|'>='|'<>'|'!=' $matcher
*/
protected function matchesCakeVersion(string $matcher, string $version): bool
{
$repositoryManager = $this->composer->getRepositoryManager();
/** @phpstan-ignore-next-line */
if (!$repositoryManager) {
return false;
}
$repos = $repositoryManager->getLocalRepository();
/** @phpstan-ignore-next-line */
if (!$repos) {
return false;
}
return $repos->findPackage('cakephp/cakephp', new Constraint($matcher, $version)) !== null;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class ChefInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'cookbook' => 'Chef/{$vendor}/{$name}/',
'role' => 'Chef/roles/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class CiviCrmInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'ext' => 'ext/{$name}/'
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class ClanCatsFrameworkInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'ship' => 'CCF/orbit/{$name}/',
'theme' => 'CCF/app/themes/{$name}/',
);
}

View File

@ -0,0 +1,36 @@
<?php
namespace Composer\Installers;
class CockpitInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'cockpit/modules/addons/{$name}/',
);
/**
* Format module name.
*
* Strip `module-` prefix from package name.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] == 'cockpit-module') {
return $this->inflectModuleVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
public function inflectModuleVars(array $vars): array
{
$vars['name'] = ucfirst($this->pregReplace('/cockpit-/i', '', $vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class CodeIgniterInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'library' => 'application/libraries/{$name}/',
'third-party' => 'application/third_party/{$name}/',
'module' => 'application/modules/{$name}/',
);
}

View File

@ -0,0 +1,15 @@
<?php
namespace Composer\Installers;
class Concrete5Installer extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'core' => 'concrete/',
'block' => 'application/blocks/{$name}/',
'package' => 'packages/{$name}/',
'theme' => 'application/themes/{$name}/',
'update' => 'updates/{$name}/',
);
}

View File

@ -0,0 +1,15 @@
<?php
namespace Composer\Installers;
class ConcreteCMSInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'core' => 'concrete/',
'block' => 'application/blocks/{$name}/',
'package' => 'packages/{$name}/',
'theme' => 'application/themes/{$name}/',
'update' => 'updates/{$name}/',
);
}

View File

@ -0,0 +1,23 @@
<?php
namespace Composer\Installers;
class CroogoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'Plugin/{$name}/',
'theme' => 'View/Themed/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class DecibelInstaller extends BaseInstaller
{
/** @var array */
/** @var array<string, string> */
protected $locations = array(
'app' => 'app/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class DframeInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$vendor}/{$name}/',
);
}

View File

@ -0,0 +1,57 @@
<?php
namespace Composer\Installers;
class DokuWikiInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'lib/plugins/{$name}/',
'template' => 'lib/tpl/{$name}/',
);
/**
* Format package name.
*
* For package type dokuwiki-plugin, cut off a trailing '-plugin',
* or leading dokuwiki_ if present.
*
* For package type dokuwiki-template, cut off a trailing '-template' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'dokuwiki-plugin') {
return $this->inflectPluginVars($vars);
}
if ($vars['type'] === 'dokuwiki-template') {
return $this->inflectTemplateVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectPluginVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-plugin$/', '', $vars['name']);
$vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectTemplateVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-template$/', '', $vars['name']);
$vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Composer\Installers;
/**
* Class DolibarrInstaller
*
* @package Composer\Installers
* @author Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
*/
class DolibarrInstaller extends BaseInstaller
{
//TODO: Add support for scripts and themes
/** @var array<string, string> */
protected $locations = array(
'module' => 'htdocs/custom/{$name}/',
);
}

View File

@ -0,0 +1,25 @@
<?php
namespace Composer\Installers;
class DrupalInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'core' => 'core/',
'module' => 'modules/{$name}/',
'theme' => 'themes/{$name}/',
'library' => 'libraries/{$name}/',
'profile' => 'profiles/{$name}/',
'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/',
'drush' => 'drush/{$name}/',
'custom-theme' => 'themes/custom/{$name}/',
'custom-module' => 'modules/custom/{$name}/',
'custom-profile' => 'profiles/custom/{$name}/',
'drupal-multisite' => 'sites/{$name}/',
'console' => 'console/{$name}/',
'console-language' => 'console/language/{$name}/',
'config' => 'config/sync/',
'recipe' => 'recipes/{$name}',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class ElggInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'mod/{$name}/',
);
}

View File

@ -0,0 +1,14 @@
<?php
namespace Composer\Installers;
class EliasisInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'component' => 'components/{$name}/',
'module' => 'modules/{$name}/',
'plugin' => 'plugins/{$name}/',
'template' => 'templates/{$name}/',
);
}

View File

@ -0,0 +1,31 @@
<?php
namespace Composer\Installers;
use Composer\Package\PackageInterface;
class ExpressionEngineInstaller extends BaseInstaller
{
/** @var array<string, string> */
private $ee2Locations = array(
'addon' => 'system/expressionengine/third_party/{$name}/',
'theme' => 'themes/third_party/{$name}/',
);
/** @var array<string, string> */
private $ee3Locations = array(
'addon' => 'system/user/addons/{$name}/',
'theme' => 'themes/user/{$name}/',
);
public function getLocations(string $frameworkType): array
{
if ($frameworkType === 'ee2') {
$this->locations = $this->ee2Locations;
} else {
$this->locations = $this->ee3Locations;
}
return $this->locations;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class EzPlatformInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'meta-assets' => 'web/assets/ezplatform/',
'assets' => 'web/assets/ezplatform/{$name}/',
);
}

View File

@ -0,0 +1,58 @@
<?php
namespace Composer\Installers;
class ForkCMSInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = [
'module' => 'src/Modules/{$name}/',
'theme' => 'src/Themes/{$name}/'
];
/**
* Format package name.
*
* For package type fork-cms-module, cut off a trailing '-plugin' if present.
*
* For package type fork-cms-theme, cut off a trailing '-theme' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'fork-cms-module') {
return $this->inflectModuleVars($vars);
}
if ($vars['type'] === 'fork-cms-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectModuleVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/^fork-cms-|-module|ForkCMS|ForkCms|Forkcms|forkcms|Module$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces
$vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make module name camelcased
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectThemeVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/^fork-cms-|-theme|ForkCMS|ForkCms|Forkcms|forkcms|Theme$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces
$vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make theme name camelcased
return $vars;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class FuelInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'fuel/app/modules/{$name}/',
'package' => 'fuel/packages/{$name}/',
'theme' => 'fuel/app/themes/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class FuelphpInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'component' => 'components/{$name}/',
);
}

View File

@ -0,0 +1,29 @@
<?php
namespace Composer\Installers;
class GravInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'user/plugins/{$name}/',
'theme' => 'user/themes/{$name}/',
);
/**
* Format package name
*/
public function inflectPackageVars(array $vars): array
{
$restrictedWords = implode('|', array_keys($this->locations));
$vars['name'] = strtolower($vars['name']);
$vars['name'] = $this->pregReplace(
'/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
'$1',
$vars['name']
);
return $vars;
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Composer\Installers;
class HuradInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
'theme' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$nameParts = explode('/', $vars['name']);
foreach ($nameParts as &$value) {
$value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value));
$value = str_replace(array('-', '_'), ' ', $value);
$value = str_replace(' ', '', ucwords($value));
}
$vars['name'] = implode('/', $nameParts);
return $vars;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class ImageCMSInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'template' => 'templates/{$name}/',
'module' => 'application/modules/{$name}/',
'library' => 'application/libraries/{$name}/',
);
}

View File

@ -0,0 +1,288 @@
<?php
namespace Composer\Installers;
use Composer\Composer;
use Composer\Installer\BinaryInstaller;
use Composer\Installer\LibraryInstaller;
use Composer\IO\IOInterface;
use Composer\Package\Package;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Util\Filesystem;
use React\Promise\PromiseInterface;
class Installer extends LibraryInstaller
{
/**
* Package types to installer class map
*
* @var array<string, string>
*/
private $supportedTypes = array(
'akaunting' => 'AkauntingInstaller',
'asgard' => 'AsgardInstaller',
'attogram' => 'AttogramInstaller',
'agl' => 'AglInstaller',
'annotatecms' => 'AnnotateCmsInstaller',
'bitrix' => 'BitrixInstaller',
'botble' => 'BotbleInstaller',
'bonefish' => 'BonefishInstaller',
'cakephp' => 'CakePHPInstaller',
'chef' => 'ChefInstaller',
'civicrm' => 'CiviCrmInstaller',
'ccframework' => 'ClanCatsFrameworkInstaller',
'cockpit' => 'CockpitInstaller',
'codeigniter' => 'CodeIgniterInstaller',
'concrete5' => 'Concrete5Installer',
'concretecms' => 'ConcreteCMSInstaller',
'croogo' => 'CroogoInstaller',
'dframe' => 'DframeInstaller',
'dokuwiki' => 'DokuWikiInstaller',
'dolibarr' => 'DolibarrInstaller',
'decibel' => 'DecibelInstaller',
'drupal' => 'DrupalInstaller',
'elgg' => 'ElggInstaller',
'eliasis' => 'EliasisInstaller',
'ee3' => 'ExpressionEngineInstaller',
'ee2' => 'ExpressionEngineInstaller',
'ezplatform' => 'EzPlatformInstaller',
'fork' => 'ForkCMSInstaller',
'fuel' => 'FuelInstaller',
'fuelphp' => 'FuelphpInstaller',
'grav' => 'GravInstaller',
'hurad' => 'HuradInstaller',
'tastyigniter' => 'TastyIgniterInstaller',
'imagecms' => 'ImageCMSInstaller',
'itop' => 'ItopInstaller',
'kanboard' => 'KanboardInstaller',
'known' => 'KnownInstaller',
'kodicms' => 'KodiCMSInstaller',
'kohana' => 'KohanaInstaller',
'lms' => 'LanManagementSystemInstaller',
'laravel' => 'LaravelInstaller',
'lavalite' => 'LavaLiteInstaller',
'lithium' => 'LithiumInstaller',
'magento' => 'MagentoInstaller',
'majima' => 'MajimaInstaller',
'mantisbt' => 'MantisBTInstaller',
'mako' => 'MakoInstaller',
'matomo' => 'MatomoInstaller',
'maya' => 'MayaInstaller',
'mautic' => 'MauticInstaller',
'mediawiki' => 'MediaWikiInstaller',
'miaoxing' => 'MiaoxingInstaller',
'microweber' => 'MicroweberInstaller',
'modulework' => 'MODULEWorkInstaller',
'modx' => 'ModxInstaller',
'modxevo' => 'MODXEvoInstaller',
'moodle' => 'MoodleInstaller',
'october' => 'OctoberInstaller',
'ontowiki' => 'OntoWikiInstaller',
'oxid' => 'OxidInstaller',
'osclass' => 'OsclassInstaller',
'pxcms' => 'PxcmsInstaller',
'phpbb' => 'PhpBBInstaller',
'piwik' => 'PiwikInstaller',
'plentymarkets'=> 'PlentymarketsInstaller',
'ppi' => 'PPIInstaller',
'puppet' => 'PuppetInstaller',
'radphp' => 'RadPHPInstaller',
'phifty' => 'PhiftyInstaller',
'porto' => 'PortoInstaller',
'processwire' => 'ProcessWireInstaller',
'quicksilver' => 'PantheonInstaller',
'redaxo' => 'RedaxoInstaller',
'redaxo5' => 'Redaxo5Installer',
'reindex' => 'ReIndexInstaller',
'roundcube' => 'RoundcubeInstaller',
'shopware' => 'ShopwareInstaller',
'sitedirect' => 'SiteDirectInstaller',
'silverstripe' => 'SilverStripeInstaller',
'smf' => 'SMFInstaller',
'starbug' => 'StarbugInstaller',
'sydes' => 'SyDESInstaller',
'sylius' => 'SyliusInstaller',
'tao' => 'TaoInstaller',
'thelia' => 'TheliaInstaller',
'tusk' => 'TuskInstaller',
'userfrosting' => 'UserFrostingInstaller',
'vanilla' => 'VanillaInstaller',
'whmcs' => 'WHMCSInstaller',
'winter' => 'WinterInstaller',
'wolfcms' => 'WolfCMSInstaller',
'wordpress' => 'WordPressInstaller',
'yawik' => 'YawikInstaller',
'zend' => 'ZendInstaller',
'zikula' => 'ZikulaInstaller',
'prestashop' => 'PrestashopInstaller'
);
/**
* Disables installers specified in main composer extra installer-disable
* list
*/
public function __construct(
IOInterface $io,
Composer $composer,
string $type = 'library',
?Filesystem $filesystem = null,
?BinaryInstaller $binaryInstaller = null
) {
parent::__construct($io, $composer, $type, $filesystem, $binaryInstaller);
$this->removeDisabledInstallers();
}
/**
* {@inheritDoc}
*/
public function getInstallPath(PackageInterface $package)
{
$type = $package->getType();
$frameworkType = $this->findFrameworkType($type);
if ($frameworkType === false) {
throw new \InvalidArgumentException(
'Sorry the package type of this package is not yet supported.'
);
}
$class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
/**
* @var BaseInstaller
*/
$installer = new $class($package, $this->composer, $this->getIO());
$path = $installer->getInstallPath($package, $frameworkType);
if (!$this->filesystem->isAbsolutePath($path)) {
$path = getcwd() . '/' . $path;
}
return $path;
}
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
{
$installPath = $this->getPackageBasePath($package);
$io = $this->io;
$outputStatus = function () use ($io, $installPath) {
$io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? '<comment>deleted</comment>' : '<error>not deleted</error>'));
};
$promise = parent::uninstall($repo, $package);
// Composer v2 might return a promise here
if ($promise instanceof PromiseInterface) {
return $promise->then($outputStatus);
}
// If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async)
$outputStatus();
return null;
}
/**
* {@inheritDoc}
*
* @param string $packageType
*/
public function supports($packageType)
{
$frameworkType = $this->findFrameworkType($packageType);
if ($frameworkType === false) {
return false;
}
$locationPattern = $this->getLocationPattern($frameworkType);
return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
}
/**
* Finds a supported framework type if it exists and returns it
*
* @return string|false
*/
protected function findFrameworkType(string $type)
{
krsort($this->supportedTypes);
foreach ($this->supportedTypes as $key => $val) {
if ($key === substr($type, 0, strlen($key))) {
return substr($type, 0, strlen($key));
}
}
return false;
}
/**
* Get the second part of the regular expression to check for support of a
* package type
*/
protected function getLocationPattern(string $frameworkType): string
{
$pattern = null;
if (!empty($this->supportedTypes[$frameworkType])) {
$frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
/** @var BaseInstaller $framework */
$framework = new $frameworkClass(new Package('dummy/pkg', '1.0.0.0', '1.0.0'), $this->composer, $this->getIO());
$locations = array_keys($framework->getLocations($frameworkType));
if ($locations) {
$pattern = '(' . implode('|', $locations) . ')';
}
}
return $pattern ?: '(\w+)';
}
private function getIO(): IOInterface
{
return $this->io;
}
/**
* Look for installers set to be disabled in composer's extra config and
* remove them from the list of supported installers.
*
* Globals:
* - true, "all", and "*" - disable all installers.
* - false - enable all installers (useful with
* wikimedia/composer-merge-plugin or similar)
*/
protected function removeDisabledInstallers(): void
{
$extra = $this->composer->getPackage()->getExtra();
if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
// No installers are disabled
return;
}
// Get installers to disable
$disable = $extra['installer-disable'];
// Ensure $disabled is an array
if (!is_array($disable)) {
$disable = array($disable);
}
// Check which installers should be disabled
$all = array(true, "all", "*");
$intersect = array_intersect($all, $disable);
if (!empty($intersect)) {
// Disable all installers
$this->supportedTypes = array();
return;
}
// Disable specified installers
foreach ($disable as $key => $installer) {
if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
unset($this->supportedTypes[$installer]);
}
}
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class ItopInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'extension' => 'extensions/{$name}/',
);
}

View File

@ -0,0 +1,20 @@
<?php
namespace Composer\Installers;
/**
*
* Installer for kanboard plugins
*
* kanboard.net
*
* Class KanboardInstaller
* @package Composer\Installers
*/
class KanboardInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class KnownInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'IdnoPlugins/{$name}/',
'theme' => 'Themes/{$name}/',
'console' => 'ConsolePlugins/{$name}/',
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class KodiCMSInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'cms/plugins/{$name}/',
'media' => 'cms/media/vendor/{$name}/'
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class KohanaInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,27 @@
<?php
namespace Composer\Installers;
class LanManagementSystemInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
'template' => 'templates/{$name}/',
'document-template' => 'documents/templates/{$name}/',
'userpanel-module' => 'userpanel/modules/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class LaravelInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'library' => 'libraries/{$name}/',
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class LavaLiteInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'package' => 'packages/{$vendor}/{$name}/',
'theme' => 'public/themes/{$name}/',
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class LithiumInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'library' => 'libraries/{$name}/',
'source' => 'libraries/_source/{$name}/',
);
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class MODULEWorkInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,18 @@
<?php
namespace Composer\Installers;
/**
* An installer to handle MODX Evolution specifics when installing packages.
*/
class MODXEvoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'snippet' => 'assets/snippets/{$name}/',
'plugin' => 'assets/plugins/{$name}/',
'module' => 'assets/modules/{$name}/',
'template' => 'assets/templates/{$name}/',
'lib' => 'assets/lib/{$name}/'
);
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class MagentoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'theme' => 'app/design/frontend/{$name}/',
'skin' => 'skin/frontend/default/{$name}/',
'library' => 'lib/{$name}/',
);
}

View File

@ -0,0 +1,46 @@
<?php
namespace Composer\Installers;
/**
* Plugin/theme installer for majima
* @author David Neustadt
*/
class MajimaInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Transforms the names
*
* @param array<string, string> $vars
* @return array<string, string>
*/
public function inflectPackageVars(array $vars): array
{
return $this->correctPluginName($vars);
}
/**
* Change hyphenated names to camelcase
*
* @param array<string, string> $vars
* @return array<string, string>
*/
private function correctPluginName(array $vars): array
{
$camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
return strtoupper($matches[0][1]);
}, $vars['name']);
if (null === $camelCasedName) {
throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error());
}
$vars['name'] = ucfirst($camelCasedName);
return $vars;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class MakoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'package' => 'app/packages/{$name}/',
);
}

View File

@ -0,0 +1,25 @@
<?php
namespace Composer\Installers;
use Composer\DependencyResolver\Pool;
class MantisBTInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Composer\Installers;
/**
* Class MatomoInstaller
*
* @package Composer\Installers
*/
class MatomoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Composer\Installers;
use Composer\Package\PackageInterface;
class MauticInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
'theme' => 'themes/{$name}/',
'core' => 'app/',
);
private function getDirectoryName(): string
{
$extra = $this->package->getExtra();
if (!empty($extra['install-directory-name'])) {
return $extra['install-directory-name'];
}
return $this->toCamelCase($this->package->getPrettyName());
}
private function toCamelCase(string $packageName): string
{
return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName))));
}
/**
* Format package name of mautic-plugins to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') {
$directoryName = $this->getDirectoryName();
$vars['name'] = $directoryName;
}
return $vars;
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Composer\Installers;
class MayaInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
);
/**
* Format package name.
*
* For package type maya-module, cut off a trailing '-module' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'maya-module') {
return $this->inflectModuleVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectModuleVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']);
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace Composer\Installers;
class MediaWikiInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'core' => 'core/',
'extension' => 'extensions/{$name}/',
'skin' => 'skins/{$name}/',
);
/**
* Format package name.
*
* For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
* to CamelCase keeping existing uppercase chars.
*
* For package type mediawiki-skin, cut off a trailing '-skin' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'mediawiki-extension') {
return $this->inflectExtensionVars($vars);
}
if ($vars['type'] === 'mediawiki-skin') {
return $this->inflectSkinVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectExtensionVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-extension$/', '', $vars['name']);
$vars['name'] = str_replace('-', ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectSkinVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/-skin$/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class MiaoxingInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
}

View File

@ -0,0 +1,145 @@
<?php
namespace Composer\Installers;
class MicroweberInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'userfiles/modules/{$install_item_dir}/',
'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/',
'template' => 'userfiles/templates/{$install_item_dir}/',
'element' => 'userfiles/elements/{$install_item_dir}/',
'vendor' => 'vendor/{$install_item_dir}/',
'components' => 'components/{$install_item_dir}/'
);
/**
* Format package name.
*
* For package type microweber-module, cut off a trailing '-module' if present
*
* For package type microweber-template, cut off a trailing '-template' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($this->package->getTargetDir() !== null && $this->package->getTargetDir() !== '') {
$vars['install_item_dir'] = $this->package->getTargetDir();
} else {
$vars['install_item_dir'] = $vars['name'];
if ($vars['type'] === 'microweber-template') {
return $this->inflectTemplateVars($vars);
}
if ($vars['type'] === 'microweber-templates') {
return $this->inflectTemplatesVars($vars);
}
if ($vars['type'] === 'microweber-core') {
return $this->inflectCoreVars($vars);
}
if ($vars['type'] === 'microweber-adapter') {
return $this->inflectCoreVars($vars);
}
if ($vars['type'] === 'microweber-module') {
return $this->inflectModuleVars($vars);
}
if ($vars['type'] === 'microweber-modules') {
return $this->inflectModulesVars($vars);
}
if ($vars['type'] === 'microweber-skin') {
return $this->inflectSkinVars($vars);
}
if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
return $this->inflectElementVars($vars);
}
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectTemplateVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-template$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/template-$/', '', $vars['install_item_dir']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectTemplatesVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-templates$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/templates-$/', '', $vars['install_item_dir']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectCoreVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-providers$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/-provider$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/-adapter$/', '', $vars['install_item_dir']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectModuleVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-module$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/module-$/', '', $vars['install_item_dir']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectModulesVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-modules$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/modules-$/', '', $vars['install_item_dir']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectSkinVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-skin$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/skin-$/', '', $vars['install_item_dir']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectElementVars(array $vars): array
{
$vars['install_item_dir'] = $this->pregReplace('/-elements$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/elements-$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/-element$/', '', $vars['install_item_dir']);
$vars['install_item_dir'] = $this->pregReplace('/element-$/', '', $vars['install_item_dir']);
return $vars;
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Composer\Installers;
/**
* An installer to handle MODX specifics when installing packages.
*/
class ModxInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'extra' => 'core/packages/{$name}/'
);
}

View File

@ -0,0 +1,73 @@
<?php
namespace Composer\Installers;
class MoodleInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'mod' => 'mod/{$name}/',
'admin_report' => 'admin/report/{$name}/',
'atto' => 'lib/editor/atto/plugins/{$name}/',
'tool' => 'admin/tool/{$name}/',
'assignment' => 'mod/assignment/type/{$name}/',
'assignsubmission' => 'mod/assign/submission/{$name}/',
'assignfeedback' => 'mod/assign/feedback/{$name}/',
'antivirus' => 'lib/antivirus/{$name}/',
'auth' => 'auth/{$name}/',
'availability' => 'availability/condition/{$name}/',
'block' => 'blocks/{$name}/',
'booktool' => 'mod/book/tool/{$name}/',
'cachestore' => 'cache/stores/{$name}/',
'cachelock' => 'cache/locks/{$name}/',
'calendartype' => 'calendar/type/{$name}/',
'communication' => 'communication/provider/{$name}/',
'customfield' => 'customfield/field/{$name}/',
'fileconverter' => 'files/converter/{$name}/',
'format' => 'course/format/{$name}/',
'coursereport' => 'course/report/{$name}/',
'contenttype' => 'contentbank/contenttype/{$name}/',
'customcertelement' => 'mod/customcert/element/{$name}/',
'datafield' => 'mod/data/field/{$name}/',
'dataformat' => 'dataformat/{$name}/',
'datapreset' => 'mod/data/preset/{$name}/',
'editor' => 'lib/editor/{$name}/',
'enrol' => 'enrol/{$name}/',
'filter' => 'filter/{$name}/',
'forumreport' => 'mod/forum/report/{$name}/',
'gradeexport' => 'grade/export/{$name}/',
'gradeimport' => 'grade/import/{$name}/',
'gradereport' => 'grade/report/{$name}/',
'gradingform' => 'grade/grading/form/{$name}/',
'h5plib' => 'h5p/h5plib/{$name}/',
'local' => 'local/{$name}/',
'logstore' => 'admin/tool/log/store/{$name}/',
'ltisource' => 'mod/lti/source/{$name}/',
'ltiservice' => 'mod/lti/service/{$name}/',
'media' => 'media/player/{$name}/',
'message' => 'message/output/{$name}/',
'mlbackend' => 'lib/mlbackend/{$name}/',
'mnetservice' => 'mnet/service/{$name}/',
'paygw' => 'payment/gateway/{$name}/',
'plagiarism' => 'plagiarism/{$name}/',
'portfolio' => 'portfolio/{$name}/',
'qbank' => 'question/bank/{$name}/',
'qbehaviour' => 'question/behaviour/{$name}/',
'qformat' => 'question/format/{$name}/',
'qtype' => 'question/type/{$name}/',
'quizaccess' => 'mod/quiz/accessrule/{$name}/',
'quiz' => 'mod/quiz/report/{$name}/',
'report' => 'report/{$name}/',
'repository' => 'repository/{$name}/',
'scormreport' => 'mod/scorm/report/{$name}/',
'search' => 'search/engine/{$name}/',
'theme' => 'theme/{$name}/',
'tiny' => 'lib/editor/tiny/plugins/{$name}/',
'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
'profilefield' => 'user/profile/field/{$name}/',
'webservice' => 'webservice/{$name}/',
'workshopallocation' => 'mod/workshop/allocation/{$name}/',
'workshopeval' => 'mod/workshop/eval/{$name}/',
'workshopform' => 'mod/workshop/form/{$name}/'
);
}

View File

@ -0,0 +1,57 @@
<?php
namespace Composer\Installers;
class OctoberInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
'plugin' => 'plugins/{$vendor}/{$name}/',
'theme' => 'themes/{$vendor}-{$name}/'
);
/**
* Format package name.
*
* For package type october-plugin, cut off a trailing '-plugin' if present.
*
* For package type october-theme, cut off a trailing '-theme' if present.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'october-plugin') {
return $this->inflectPluginVars($vars);
}
if ($vars['type'] === 'october-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectPluginVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/^oc-|-plugin$/', '', $vars['name']);
$vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']);
return $vars;
}
/**
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectThemeVars(array $vars): array
{
$vars['name'] = $this->pregReplace('/^oc-|-theme$/', '', $vars['name']);
$vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']);
return $vars;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Composer\Installers;
class OntoWikiInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'extension' => 'extensions/{$name}/',
'theme' => 'extensions/themes/{$name}/',
'translation' => 'extensions/translations/{$name}/',
);
/**
* Format package name to lower case and remove ".ontowiki" suffix
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($vars['name']);
$vars['name'] = $this->pregReplace('/.ontowiki$/', '', $vars['name']);
$vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']);
$vars['name'] = $this->pregReplace('/-translation$/', '', $vars['name']);
return $vars;
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Composer\Installers;
class OsclassInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'oc-content/plugins/{$name}/',
'theme' => 'oc-content/themes/{$name}/',
'language' => 'oc-content/languages/{$name}/',
);
}

View File

@ -0,0 +1,49 @@
<?php
namespace Composer\Installers;
use Composer\Package\PackageInterface;
class OxidInstaller extends BaseInstaller
{
const VENDOR_PATTERN = '/^modules\/(?P<vendor>.+)\/.+/';
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
'theme' => 'application/views/{$name}/',
'out' => 'out/{$name}/',
);
public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string
{
$installPath = parent::getInstallPath($package, $frameworkType);
$type = $this->package->getType();
if ($type === 'oxid-module') {
$this->prepareVendorDirectory($installPath);
}
return $installPath;
}
/**
* Makes sure there is a vendormetadata.php file inside
* the vendor folder if there is a vendor folder.
*/
protected function prepareVendorDirectory(string $installPath): void
{
$matches = '';
$hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
if (!$hasVendorDirectory) {
return;
}
$vendorDirectory = $matches['vendor'];
$vendorPath = getcwd() . '/modules/' . $vendorDirectory;
if (!file_exists($vendorPath)) {
mkdir($vendorPath, 0755, true);
}
$vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
touch($vendorMetaDataPath);
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class PPIInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class PantheonInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'script' => 'web/private/scripts/quicksilver/{$name}',
'module' => 'web/private/scripts/quicksilver/{$name}',
);
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class PhiftyInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'bundle' => 'bundles/{$name}/',
'library' => 'libraries/{$name}/',
'framework' => 'frameworks/{$name}/',
);
}

View File

@ -0,0 +1,13 @@
<?php
namespace Composer\Installers;
class PhpBBInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'extension' => 'ext/{$vendor}/{$name}/',
'language' => 'language/{$name}/',
'style' => 'styles/{$name}/',
);
}

View File

@ -0,0 +1,28 @@
<?php
namespace Composer\Installers;
/**
* Class PiwikInstaller
*
* @package Composer\Installers
*/
class PiwikInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Composer\Installers;
class PlentymarketsInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => '{$name}/'
);
/**
* Remove hyphen, "plugin" and format to camelcase
*/
public function inflectPackageVars(array $vars): array
{
$nameBits = explode("-", $vars['name']);
foreach ($nameBits as $key => $name) {
$nameBits[$key] = ucfirst($name);
if (strcasecmp($name, "Plugin") == 0) {
unset($nameBits[$key]);
}
}
$vars['name'] = implode('', $nameBits);
return $vars;
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Composer\Installers;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class Plugin implements PluginInterface
{
/** @var Installer */
private $installer;
public function activate(Composer $composer, IOInterface $io): void
{
$this->installer = new Installer($io, $composer);
$composer->getInstallationManager()->addInstaller($this->installer);
}
public function deactivate(Composer $composer, IOInterface $io): void
{
$composer->getInstallationManager()->removeInstaller($this->installer);
}
public function uninstall(Composer $composer, IOInterface $io): void
{
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Composer\Installers;
class PortoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'container' => 'app/Containers/{$name}/',
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class PrestashopInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
'theme' => 'themes/{$name}/',
);
}

View File

@ -0,0 +1,23 @@
<?php
namespace Composer\Installers;
class ProcessWireInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'site/modules/{$name}/',
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
$vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
$vars['name'] = str_replace(' ', '', ucwords($vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class PuppetInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'modules/{$name}/',
);
}

View File

@ -0,0 +1,62 @@
<?php
namespace Composer\Installers;
class PxcmsInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'app/Modules/{$name}/',
'theme' => 'themes/{$name}/',
);
/**
* Format package name.
*/
public function inflectPackageVars(array $vars): array
{
if ($vars['type'] === 'pxcms-module') {
return $this->inflectModuleVars($vars);
}
if ($vars['type'] === 'pxcms-theme') {
return $this->inflectThemeVars($vars);
}
return $vars;
}
/**
* For package type pxcms-module, cut off a trailing '-plugin' if present.
*
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectModuleVars(array $vars): array
{
$vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
$vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
$vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); // strip out -module
$vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
$vars['name'] = ucwords($vars['name']); // make module name camelcased
return $vars;
}
/**
* For package type pxcms-module, cut off a trailing '-plugin' if present.
*
* @param array<string, string> $vars
* @return array<string, string>
*/
protected function inflectThemeVars(array $vars): array
{
$vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
$vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
$vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); // strip out -theme
$vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
$vars['name'] = ucwords($vars['name']); // make module name camelcased
return $vars;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Composer\Installers;
class RadPHPInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'bundle' => 'src/{$name}/'
);
/**
* Format package name to CamelCase
*/
public function inflectPackageVars(array $vars): array
{
$nameParts = explode('/', $vars['name']);
foreach ($nameParts as &$value) {
$value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value));
$value = str_replace(array('-', '_'), ' ', $value);
$value = str_replace(' ', '', ucwords($value));
}
$vars['name'] = implode('/', $nameParts);
return $vars;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class ReIndexInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'theme' => 'themes/{$name}/',
'plugin' => 'plugins/{$name}/'
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class Redaxo5Installer extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'addon' => 'redaxo/src/addons/{$name}/',
'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/'
);
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class RedaxoInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'addon' => 'redaxo/include/addons/{$name}/',
'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
);
}

View File

@ -0,0 +1,21 @@
<?php
namespace Composer\Installers;
class RoundcubeInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'plugin' => 'plugins/{$name}/',
);
/**
* Lowercase name and changes the name to a underscores
*/
public function inflectPackageVars(array $vars): array
{
$vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
return $vars;
}
}

View File

@ -0,0 +1,12 @@
<?php
namespace Composer\Installers;
class SMFInstaller extends BaseInstaller
{
/** @var array<string, string> */
protected $locations = array(
'module' => 'Sources/{$name}/',
'theme' => 'Themes/{$name}/',
);
}

Some files were not shown because too many files have changed in this diff Show More