diff --git a/app/code/Magento/Catalog/view/frontend/templates/category/image.phtml b/app/code/Magento/Catalog/view/frontend/templates/category/image.phtml
index 8f72e4713d22b..b11fa08befbe4 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/category/image.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/category/image.phtml
@@ -19,6 +19,7 @@
$_category = $block->getCurrentCategory();
$_imgHtml = '';
if ($_imgUrl = $block->getImage()->getUrl($_category)) {
+ if(file_exists($_imgUrl)) {
$_imgHtml = '
';
$_imgHtml = $block->getOutput()->categoryAttribute($_category, $_imgHtml, 'image');
/* @noEscape */ echo $_imgHtml;
+ }
}
?>
diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Datetime.php b/lib/internal/Magento/Framework/Data/Form/Element/Datetime.php
new file mode 100644
index 0000000000000..a1af806a70fb0
--- /dev/null
+++ b/lib/internal/Magento/Framework/Data/Form/Element/Datetime.php
@@ -0,0 +1,204 @@
+
+ */
+
+namespace Magento\Framework\Data\Form\Element;
+
+use Magento\Framework\Escaper;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
+
+/**
+ * Date element
+ */
+class Datetime extends AbstractElement
+{
+ /**
+ * @var \DateTime
+ */
+ protected $_value;
+
+ /**
+ * @var TimezoneInterface
+ */
+ protected $localeDate;
+
+ /**
+ * @param Factory $factoryElement
+ * @param CollectionFactory $factoryCollection
+ * @param Escaper $escaper
+ * @param TimezoneInterface $localeDate
+ * @param array $data
+ */
+ public function __construct(
+ Factory $factoryElement,
+ CollectionFactory $factoryCollection,
+ Escaper $escaper,
+ TimezoneInterface $localeDate,
+ $data = []
+ ) {
+ $this->localeDate = $localeDate;
+ parent::__construct($factoryElement, $factoryCollection, $escaper, $data);
+ $this->setType('text');
+ $this->setExtType('textfield');
+ if (isset($data['value'])) {
+ $this->setValue($data['value']);
+ }
+ }
+
+ /**
+ * Check if a string is a date value
+ *
+ * @param string $value
+ * @return bool
+ */
+ private function isDate(string $value): bool
+ {
+ $date = date_parse($value);
+
+ return !empty($date['year']) && !empty($date['month']) && !empty($date['day']);
+ }
+
+ /**
+ * If script executes on x64 system, converts large numeric values to timestamp limit
+ *
+ * @param int $value
+ * @return int
+ */
+ protected function _toTimestamp($value)
+ {
+ $value = (int)$value;
+ if ($value > 3155760000) {
+ $value = 0;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Set date value
+ *
+ * @param mixed $value
+ * @return $this
+ */
+ public function setValue($value)
+ {
+ if (empty($value)) {
+ $this->_value = '';
+ return $this;
+ }
+ if ($value instanceof \DateTimeInterface) {
+ $this->_value = $value;
+ return $this;
+ }
+ try {
+ if (preg_match('/^[0-9]+$/', $value)) {
+ $this->_value = (new \DateTime())->setTimestamp($this->_toTimestamp($value));
+ } elseif (is_string($value) && $this->isDate($value)) {
+ $this->_value = new \DateTime($value, new \DateTimeZone($this->localeDate->getConfigTimezone()));
+ } else {
+ $this->_value = '';
+ }
+ } catch (\Exception $e) {
+ $this->_value = '';
+ }
+ return $this;
+ }
+
+ /**
+ * Get date value as string.
+ *
+ * Format can be specified, or it will be taken from $this->getFormat()
+ *
+ * @param string $format (compatible with \DateTime)
+ * @return string
+ */
+ public function getValue($format = null)
+ {
+ if (empty($this->_value)) {
+ return '';
+ }
+ if (null === $format) {
+ $format = $this->getDateFormat();
+ $format .= ($format && $this->getTimeFormat()) ? ' ' : '';
+ $format .= $this->getTimeFormat() ? $this->getTimeFormat() : '';
+ }
+ return $this->localeDate->formatDateTime(
+ $this->_value,
+ null,
+ null,
+ null,
+ $this->_value->getTimezone(),
+ $format
+ );
+ }
+
+ /**
+ * Get value instance, if any
+ *
+ * @return \DateTime
+ */
+ public function getValueInstance()
+ {
+ if (empty($this->_value)) {
+ return null;
+ }
+ return $this->_value;
+ }
+
+ /**
+ * Output the input field and assign calendar instance to it.
+ * In order to output the date:
+ * - the value must be instantiated (\DateTime)
+ * - output format must be set (compatible with \DateTime)
+ *
+ * @throws \Exception
+ * @return string
+ */
+ public function getElementHtml()
+ {
+ $this->addClass('admin__control-text input-text input-date');
+ $dateFormat = $this->getDateFormat() ?: $this->getFormat();
+ $dateFormat = 'mm/dd/yy';
+ $timeFormat = $this->getTimeFormat();
+ if (empty($dateFormat)) {
+ throw new \Exception(
+ 'Output format is not specified. ' .
+ 'Please specify "format" key in constructor, or set it using setFormat().'
+ );
+ }
+
+ $dataInit = 'data-mage-init="' . $this->_escape(
+ json_encode(
+ [
+ 'calendar' => [
+ 'dateFormat' => $dateFormat,
+ 'showsTime' => true,
+ 'timeFormat' => 'HH:mm',
+ 'buttonImage' => $this->getImage(),
+ 'buttonText' => 'Select Date',
+ 'changeYear' => true,
+ ],
+ ]
+ )
+ ) . '"';
+
+ $html = sprintf(
+ '',
+ $this->getName(),
+ $this->getHtmlId(),
+ $this->_escape($this->getValue()),
+ $this->serialize($this->getHtmlAttributes()),
+ $dataInit
+ );
+ $html .= $this->getAfterElementHtml();
+ return $html;
+ }
+}
diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Factory.php b/lib/internal/Magento/Framework/Data/Form/Element/Factory.php
index 582b0c8cf6549..86b2c60fcfb66 100644
--- a/lib/internal/Magento/Framework/Data/Form/Element/Factory.php
+++ b/lib/internal/Magento/Framework/Data/Form/Element/Factory.php
@@ -29,6 +29,7 @@ class Factory
'checkboxes',
'column',
'date',
+ 'datetime',
'editablemultiselect',
'editor',
'fieldset',