downloads = $downloads; } /** * The component slug. * * @return string */ public function slug(): string { return 'downloads-list'; } /** * The attribute schema adapters map their controls onto. * * @return array> */ public function schema(): array { return array( 'title' => array( 'type' => 'string', 'default' => __( 'Your downloads', 'releasecart' ), 'control' => 'text', 'label' => __( 'Title', 'releasecart' ), ), 'show_updates' => array( 'type' => 'boolean', 'default' => true, 'control' => 'toggle', 'label' => __( 'Show available updates', 'releasecart' ), ), ); } /** * Render the downloads list, the empty state, or the logged-out prompt. * * @param array $attrs Resolved attribute values. * @param RenderContext $ctx Per-request customer/license state. * @return string Escaped HTML. */ public function render( array $attrs, RenderContext $ctx ): string { $showUpdates = (bool) $attrs['show_updates']; $data = array( 'title' => (string) $attrs['title'], 'show_updates' => $showUpdates, 'login_url' => '', 'downloads' => array(), 'updates' => array(), ); // Show a sample list instead of a login prompt in the editor. if ( ! is_user_logged_in() ) { if ( $ctx->isEditorPreview() ) { return $this->renderSample( $this->sampleData( $data['title'], $showUpdates ), $ctx ); } $data['state'] = 'logged_out'; $data['login_url'] = wp_login_url( RequestUrl::current() ); return $this->renderTemplate( $data ); } $customer = $ctx->customer(); // A user without a customer record has no downloads. if ( null !== $customer ) { // Download endpoints check access again when the link is used. $ttl = 6 * HOUR_IN_SECONDS; $data['downloads'] = $this->downloads->purchasedFileEntries( $customer, 1, $ttl ); $data['updates'] = $showUpdates ? $this->downloads->updateEntries( $customer, $ttl ) : array(); } $hasContent = array() !== $data['downloads'] || array() !== $data['updates']; // Show sample data for an empty editor preview. if ( ! $hasContent && $ctx->isEditorPreview() ) { return $this->renderSample( $this->sampleData( $data['title'], $showUpdates ), $ctx ); } $data['state'] = $hasContent ? 'list' : 'empty'; return $this->renderTemplate( $data ); } /** * Sample list data for an editor preview. * * @param string $title The resolved heading. * @param bool $showUpdates Whether the updates section may render. * @return array */ private function sampleData( string $title, bool $showUpdates ): array { return array( 'state' => 'list', 'title' => $title, 'show_updates' => $showUpdates, 'login_url' => '', 'downloads' => array( array( 'product_name' => __( 'Sample product', 'releasecart' ), 'files' => array( array( 'label' => __( 'Download (.zip)', 'releasecart' ), 'download_url' => '#', ), ), ), ), 'updates' => $showUpdates ? array( array( 'product_name' => __( 'Sample product', 'releasecart' ), 'version' => '2.1.0', 'download_url' => '#', ), ) : array(), ); } }