403Webshell
Server IP : 104.21.28.229  /  Your IP : 216.73.216.142
Web Server : Apache/2
System : Linux hosting8537.lvs 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User : mienphi ( 1014)
PHP Version : 8.2.14
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/mienphi/public_html/wp-content/plugins/learnpress/assets/src/js/frontend/profile/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/mienphi/public_html/wp-content/plugins/learnpress/assets/src/js/frontend/profile/avatar.js
import { useState, useCallback, useEffect, useRef } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';
import { __, sprintf } from '@wordpress/i18n';
import Cropper from 'react-easy-crop';

export default function Avatar() {
	const [ file, setFile ] = useState();
	const [ width, setWidth ] = useState( 0 );
	const [ height, setHeight ] = useState( 0 );
	const [ crop, setCrop ] = useState( { x: 0, y: 0 } );
	const [ rotation, setRotation ] = useState( 0 );
	const [ croppedAreaPixels, setCroppedAreaPixels ] = useState( null );
	const [ naturalWidth, setNaturalWidth ] = useState( 0 );
	const [ naturalHeight, setNaturalHeight ] = useState( 0 );
	const [ loading, setLoading ] = useState( false );
	const [ skeleton, setSkeleton ] = useState( true );
	const [ uploadError, setUploadError ] = useState( '' );
	const [ notice, setNotice ] = useState( {
		type: '',
		message: '',
	} );

	const fileInput = useRef();

	useEffect( () => {
		async function getAvatar() {
			setSkeleton( true );
			try {
				const response = await apiFetch( {
					method: 'GET',
					path: 'lp/v1/profile/get-avatar',
				} );

				setWidth( response?.data?.width ? parseInt( response.data.width ) : 0 );
				setHeight( response?.data?.height ? parseInt( response.data.height ) : 0 );
				setFile( response?.data?.url ? response.data.url : '' );
			} catch ( error ) {
				setNotice( {
					type: 'error',
					message: error.message,
				} );
			}
			setSkeleton( false );
		}

		getAvatar();
	}, [] );

	function readFile( file ) {
		return new Promise( ( resolve ) => {
			const reader = new FileReader();
			reader.addEventListener( 'load', () => resolve( reader.result ), false );
			reader.readAsDataURL( file );
		} );
	}

	const onCropComplete = useCallback( ( croppedArea, croppedAreaPixels ) => {
		setCroppedAreaPixels( croppedAreaPixels );
	}, [] );

	const base64Resize = ( base64, width, height ) => {
		return new Promise( ( resolve, reject ) => {
			const canvas = document.createElement( 'canvas' );
			const img = document.createElement( 'img' );
			img.src = base64;
			img.setAttribute( 'crossOrigin', 'anonymous' );
			img.onload = () => {
				if ( img.naturalWidth > width || img.naturalHeight > height ) {
					canvas.width = width;
					canvas.height = height;
					const ctx = canvas.getContext( '2d' );
					ctx.drawImage( img, 0, 0, width, height );
					resolve( canvas.toDataURL( 'image/png' ) );
				}

				resolve( base64 );
			};
			img.onerror = ( err ) => reject( err );
		} );
	};

	const updateAvatar = useCallback( async () => {
		setLoading( { save: true } );

		try {
			const croppedImage = await getCroppedImg(
				file,
				croppedAreaPixels,
				rotation,
			);

			const imageResize = await base64Resize( croppedImage, width, height );

			const response = await apiFetch( {
				path: 'lp/v1/profile/upload-avatar',
				method: 'POST',
				data: { file: imageResize || '' },
			} );

			const { data, status, message } = await response;

			if ( status === 'success' ) {
				window.location.reload();
			}

			setNotice( {
				type: status,
				message,
			} );
		} catch ( e ) {
			setNotice( {
				type: 'error',
				message: e.message || '',
			} );
		}

		setLoading( { save: false } );
	}, [ croppedAreaPixels, rotation ] );

	const setFileInput = async ( fileUpload ) => {
		const file = await readFile( fileUpload );

		const img = new Image();
		img.src = await file;
		img.onload = await function() {
			setNaturalWidth( img.naturalWidth );
			setNaturalHeight( img.naturalHeight );

			let error = '';
			if ( parseInt( fileUpload.size ) > 2097152 ) {
				error = __( 'The file size is too large. You need to upload a file < 2MB.', 'learnpress' );
			} else if ( img.naturalWidth < width || img.naturalHeight < height ) {
				error = sprintf( __( 'The image size must be greater than or equal to %1$sx%2$spx', 'learnpress' ), width, height );
			}

			if ( error ) {
				setUploadError( error );
			} else {
				setUploadError( '' );
				setFile( file );
			}
		};
	};

	async function removeAvatar() {
		if ( confirm( __( 'Are you sure you want to remove your avatar?', 'learnpress' ) ) ) {
			setLoading( { remove: true } );
			try {
				const response = await apiFetch( {
					path: 'lp/v1/profile/remove-avatar',
					method: 'POST',
				} );

				const { data, status, message } = await response;

				setNotice( {
					type: status,
					message,
				} );

				setFile( '' );
			} catch ( e ) {
				setNotice( {
					type: 'error',
					message: e.message || '',
				} );
			}
			setLoading( { remove: false } );
		}
	}

	return (
		<div className="learnpress_avatar">
			{ ! skeleton ? (
				<>
					{ file && ! uploadError && (
						<>
							{ naturalHeight && naturalWidth ? (
								<div className="learnpress_avatar__cropper">
									<div style={ { position: 'relative', width: naturalWidth, height: naturalHeight, zIndex: 9999, maxWidth: '100%', maxHeight: '800px' } }>
										<Cropper
											image={ file }
											crop={ crop }
											zoom="1"
											cropSize={ { width, height } }
											onCropChange={ setCrop }
											onCropComplete={ onCropComplete }
										/>
									</div>

									<div>
										<button className={ `learnpress_avatar__button learnpress_avatar__button--save ${ loading?.save ? 'learnpress_avatar__button--loading' : '' }` } onClick={ updateAvatar }>{ lpProfileSettings.text_save }</button>
									</div>
								</div>
							) : (
								<div className="learnpress_avatar__cropper">
									<img src={ file } alt="" />

									<div>
										<button className={ `learnpress_avatar__button learnpress_avatar__button--replace` } onClick={ () => fileInput.current && fileInput.current.click() }>{ lpProfileSettings.text_replace }</button>
										<button className={ `learnpress_avatar__button learnpress_avatar__button--remove ${ loading?.remove ? 'learnpress_avatar__button--loading' : '' }` } onClick={ removeAvatar }>{ lpProfileSettings.text_remove }</button>
									</div>
								</div>
							) }
						</>
					) }

					<form style={ { display: ! file ? '' : 'none' } }>
						<div className="learnpress_avatar__form">
							<div className="learnpress_avatar__form-group">
								<label htmlFor="avatar-file">
									<div className="learnpress_avatar__form__upload">
										<div>
											<span><svg viewBox="64 64 896 896" focusable="false" data-icon="plus" width="1em" height="1em" fill="currentColor" aria-hidden="true"><defs><style></style></defs><path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"></path><path d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"></path></svg></span>
											<div>{ lpProfileSettings.text_upload }</div>
										</div>
									</div>
									<input ref={ fileInput } type="file" id="avatar-file" accept="image/*" onChange={ ( e ) => setFileInput( e.target.files && e.target.files.length > 0 ? e.target.files[ 0 ] : '' ) } />
								</label>
							</div>
						</div>
					</form>

					{ uploadError && (
						<div className={ `lp-ajax-message error` } style={ { display: 'block' } }>{ uploadError }</div>
					) }

					{ ! uploadError && notice && notice.type && notice.message && (
						<div className={ `lp-ajax-message ${ notice.type }` } style={ { display: 'block' } }>{ notice.message }</div>
					) }
				</>
			) : (
				<ul className="lp-skeleton-animation">
					<li style={ { width: 200, height: 200 } }></li>
					<li style={ { width: 200, height: 20 } }></li>
					<li style={ { width: 200, height: 20 } }></li>
				</ul>
			) }
		</div>
	);
}

// Link: https://codesandbox.io/s/q8q1mnr01w
const createImage = ( url ) =>
	new Promise( ( resolve, reject ) => {
		const image = new Image();
		image.addEventListener( 'load', () => resolve( image ) );
		image.addEventListener( 'error', ( error ) => reject( error ) );
		image.setAttribute( 'crossOrigin', 'anonymous' ); // needed to avoid cross-origin issues on CodeSandbox
		image.src = url;
	} );

function getRadianAngle( degreeValue ) {
	return ( degreeValue * Math.PI ) / 180;
}

/**
 * Returns the new bounding area of a rotated rectangle.
 *
 * @param width
 * @param height
 * @param rotation
 */
function rotateSize( width, height, rotation ) {
	const rotRad = getRadianAngle( rotation );

	return {
		width:
Math.abs( Math.cos( rotRad ) * width ) + Math.abs( Math.sin( rotRad ) * height ),
		height:
Math.abs( Math.sin( rotRad ) * width ) + Math.abs( Math.cos( rotRad ) * height ),
	};
}

/**
 * This function was adapted from the one in the ReadMe of https://github.com/DominicTobias/react-image-crop
 *
 * @param imageSrc
 * @param pixelCrop
 * @param rotation
 * @param flip
 */
async function getCroppedImg(
	imageSrc,
	pixelCrop,
	rotation = 0,
	flip = { horizontal: false, vertical: false }
) {
	const image = await createImage( imageSrc );
	const canvas = document.createElement( 'canvas' );
	const ctx = canvas.getContext( '2d' );

	if ( ! ctx ) {
		return null;
	}

	const rotRad = getRadianAngle( rotation );

	// calculate bounding box of the rotated image
	const { width: bBoxWidth, height: bBoxHeight } = rotateSize(
		image.width,
		image.height,
		rotation
	);

	// set canvas size to match the bounding box
	canvas.width = bBoxWidth;
	canvas.height = bBoxHeight;

	// translate canvas context to a central location to allow rotating and flipping around the center
	ctx.translate( bBoxWidth / 2, bBoxHeight / 2 );
	ctx.rotate( rotRad );
	ctx.scale( flip.horizontal ? -1 : 1, flip.vertical ? -1 : 1 );
	ctx.translate( -image.width / 2, -image.height / 2 );

	// draw rotated image
	ctx.drawImage( image, 0, 0 );

	// croppedAreaPixels values are bounding box relative
	// extract the cropped image using these values
	const data = ctx.getImageData(
		pixelCrop.x,
		pixelCrop.y,
		pixelCrop.width,
		pixelCrop.height
	);

	// set canvas width to final desired crop size - this will clear existing context
	canvas.width = pixelCrop.width;
	canvas.height = pixelCrop.height;

	// paste generated rotate image at the top left corner
	ctx.putImageData( data, 0, 0 );

	// As Base64 string
	return canvas.toDataURL( 'image/png' );
}

Youez - 2016 - github.com/yon3zu
LinuXploit