Alert: This function’s access is marked private. This means it is not intended for use by plugin or theme developers, only in other core functions. It is listed here for completeness.

LLMS_Certificates::get_export_html( int $certificate_id )

Retrieves the HTML of a certificate which can be used to create an exportable download


Description Description


Parameters Parameters

$certificate_id

(int) (Required) WP Post ID of the earned certificate


Top ↑

Return Return

(string)


Top ↑

Source Source

File: includes/class.llms.certificates.php

	private function get_export_html( $certificate_id ) {

		// create a nonce for getting the export HTML
		$token = wp_generate_password( 32, false );
		update_post_meta( $certificate_id, '_llms_auth_nonce', $token );

		// scrape the html from a one-time use URL
		$url = apply_filters( 'llms_get_certificate_export_html_url', add_query_arg( '_llms_cert_auth', $token, get_permalink( $certificate_id ) ), $certificate_id );
		$req = wp_safe_remote_get( $url, array(
			'sslverify' => false,
		) );

		// delete the token after the request
		delete_post_meta( $certificate_id, '_llms_auth_nonce', $token );

		// error?
		if ( is_wp_error( $req ) ) {
			return $req;
		}

		$html = wp_remote_retrieve_body( $req );

		if ( ! class_exists( 'DOMDocument' ) ) {
			return apply_filters( 'llms_get_certificate_export_html', $html, $certificate_id );
		}

		// don't throw or log warnings
		$libxml_state = libxml_use_internal_errors( true );

		$dom = new DOMDocument;

		if ( $dom->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ) ) ) {

			$header = $dom->getElementsByTagName( 'head' )->item( 0 );

			// remove all <scripts>
			$scripts = $dom->getElementsByTagName( 'script' );
			while ( $scripts && $scripts->length ) {
				$scripts->item( 0 )->parentNode->removeChild( $scripts->item( 0 ) );
			}

			// get all <links>
			$links = $dom->getElementsByTagName( 'link' );
			$to_replace = array();

			// inline stylesheets
			foreach ( $links as $link ) {

				// only proceed for stylesheets
				if ( 'stylesheet' !== $link->getAttribute( 'rel' ) ) {
					continue;
				}

				// save href for use later
				$href = $link->getAttribute( 'href' );

				// only include local stylesheets
				// this means that external fonts (google, for example) are excluded from the download
				// sorry... (kind of)
				if ( 0 !== strpos( $href, get_site_url() ) ) {
					continue;
				}

				// get the actual CSS
				$stylepath = strtok( str_replace( get_site_url(), untrailingslashit( ABSPATH ), $href ), '?' );
				$raw = file_get_contents( $stylepath );

				// add it to be inlined late
				$tag = $dom->createElement( 'style', $raw );
				$to_replace[] = array(
					'old' => $link,
					'new' => $tag,
				);

			}

			// do replacements, ensures cascade order is retained
			foreach ( $to_replace as $replacement ) {
				// var_dump( $replacement['old'] );
				$replacement['old']->parentNode->replaceChild( $replacement['new'], $replacement['old'] );
				// $header->replaceChild( $replacement['new'], $replacement['old'] );
			}

			// remove all remaining non stylesheet <links>
			$links = $dom->getElementsByTagName( 'link' );
			while ( $links && $links->length ) {
				$links->item( 0 )->parentNode->removeChild( $links->item( 0 ) );
			}

			// convert images to data uris
			$images = $dom->getElementsByTagName( 'img' );
			foreach ( $images as $img ) {
				$src = $img->getAttribute( 'src' );
				// only include local images
				if ( 0 !== strpos( $src, get_site_url() ) ) {
					continue;
				}
				$imgpath = strtok( str_replace( get_site_url(), untrailingslashit( ABSPATH ), $src ), '?' );
				$data = base64_encode( file_get_contents( $imgpath ) );
				$img->setAttribute( 'src', 'data:' . mime_content_type( $imgpath ) . ';base64,' . $data );
			}

			// hide print stuff
			// this is faster than traversing the dom to remove the element
			$header->appendChild( $dom->createELement( 'style', '.no-print { display: none !important; }' ) );

			// Remove the admin bar (if found).
			$admin_bar = $dom->getElementById( 'wpadminbar' );
			if ( $admin_bar ) {
				// @codingStandardsIgnoreStart WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
				$admin_bar->parentNode->removeChild( $admin_bar );
				// @codingStandardsIgnoreEnd
			}

			$html = $dom->saveHTML();

		}// End if().

		// handle errors
		libxml_clear_errors();
		// restore
		libxml_use_internal_errors( $libxml_state );

		// return the html
		return apply_filters( 'llms_get_certificate_export_html', $html, $certificate_id );

	}

Top ↑

Changelog Changelog

Changelog
Version Description
3.18.0 Introduced.


Top ↑

User Contributed Notes User Contributed Notes

You must log in before being able to contribute a note or feedback.