<commit_before><?
require 'scat.php';

// XXX Use Knockout to make title dynamic
head("Product @ Scat", true);

$id= (int)$_REQUEST['id'];

$product= Model::factory('Product')
            ->select('product.*')
            ->select('brand.name', 'brand_name')
            ->select_expr('(SELECT COUNT(DISTINCT variation)
                              FROM item
                              WHERE item.product_id = product.id)',
                          'variations')
            ->join('brand', array('product.brand_id', '=', 'brand.id'))
            ->find_one($id);

if (!$product) {
  die("No such product.");
}

$items= $product->items()
          ->order_by_asc('variation')
          ->order_by_desc('active')
          ->order_by_expr('IF(minimum_quantity OR stock, 0, 1)')
          ->order_by_asc('code')
          ->find_many();
?>
<script>
$(function() { 
var model= {
  product: <?=json_encode($product->as_array(),
                          JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK)?>,
  items: [
<?
  /* Convert each row to an object */
  echo join(", \n",
            array_map(function ($items) {
                        return json_encode($items->as_array(),
                                           JSON_PRETTY_PRINT|
                                           JSON_NUMERIC_CHECK);
                      },
                      $items));
?>
  ],
  showInactive: <?=array_reduce($items, function ($c, $i) { return $c + $i->active; }) ? 0 : 1?>
};

var viewModel= ko.mapping.fromJS(model);

viewModel.toggleActive= function (item) {
  Scat.api('item-update',
           { id: item.id(),
             active: item.active() ? 0 : 1 })
      .done(function (data) {
        // XXX Doesn't re-sort the items
        ko.mapping.fromJS(data.item, {}, item);
      });
}

viewModel.toggleProductActive= function () {
  Scat.api('product-update',
           { id: viewModel.product.id(),
             active: viewModel.product.active() == '1' ? 0 : 1 })
      .done(function (data) {
        ko.mapping.fromJS(data, {}, viewModel.product);
      });
}

viewModel.editProduct= function (self) {
  Scat.dialog('product').done(function (html) {
    var panel= $(html);

    panel.on('hidden.bs.modal', function() {
      $(this).remove();
    });

    var product= ko.mapping.toJS(self.product);

    product.departments= [];
    product.brands= [];

    var panelModel= ko.mapping.fromJS(product);

    /* Load departments */
    Scat.api('department-find', { levels: 2 })
        .done(function (data) {
          ko.mapping.fromJS(data, {}, panelModel.departments);
          // make sure correct selection is made
          panelModel.department_id.valueHasMutated();
        });

    /* Load brands */
    Scat.api('brand-list', { verbose: 1 })
        .done(function (data) {
          ko.mapping.fromJS(data, {}, panelModel.brands);
          // make sure correct selection is made
          panelModel.brand_id.valueHasMutated();
        });

    panelModel.saveProduct= function(place, ev) {
      var product= ko.mapping.toJS(panelModel); /* XXX */
      delete product.departments;
      delete product.brands;

      Scat.api('product-update', product)
          .done(function (data) {
            $(place).closest('.modal').modal('hide');
            ko.mapping.fromJS(data, {}, viewModel.product);
          });
    }

    panelModel.generateSlug= function(place, ev) {
      Scat.api('generate-slug',
               { brand: panelModel.brand_id(), name: panelModel.name() })
          .done(function (data) {
            panelModel.slug(data.slug);
          })
    }

    panelModel.selectedDepartment= ko.computed({
      read: function () {
        return this.department_id();
      },
      write: function (value) {
        if (typeof value != 'undefined' && value != '') {
          this.department_id(value);
        }
      },
      owner: panelModel
    }).extend({ notify: 'always' });

    panelModel.selectedBrand= ko.computed({
      read: function () {
        return this.brand_id();
      },
      write: function (value) {
        if (typeof value != 'undefined' && value != '') {
          this.brand_id(value);
        }
      },
      owner: panelModel
    }).extend({ notify: 'always' });

    ko.applyBindings(panelModel, panel[0]);
    panel.appendTo($('body')).modal();
  });
}

ko.applyBindings(viewModel);
});
</script>

<div class="pull-right well text-center">
  <label>
    <input type="checkbox" data-bind="checked: showInactive">
    Show inactive
  </label>
  <div>
    <button class="btn btn-primary"
            data-bind="click: editProduct">Edit</button>
  </div>
  <div>
    <button class="btn btn-xs btn-default"
            data-bind="click: toggleProductActive,
                       text: product.active() == '1' ? 'Active' : 'Inactive',
                       css: { 'btn-danger' : product.active() != '1' }">
    </button>
  </div>
</div>
<commit_msg>Handle drag&drop upload of image<commit_after><?
require 'scat.php';

// XXX Use Knockout to make title dynamic
head("Product @ Scat", true);

$id= (int)$_REQUEST['id'];

$product= Model::factory('Product')
            ->select('product.*')
            ->select('brand.name', 'brand_name')
            ->select_expr('(SELECT COUNT(DISTINCT variation)
                              FROM item
                              WHERE item.product_id = product.id)',
                          'variations')
            ->join('brand', array('product.brand_id', '=', 'brand.id'))
            ->find_one($id);

if (!$product) {
  die("No such product.");
}

$items= $product->items()
          ->order_by_asc('variation')
          ->order_by_desc('active')
          ->order_by_expr('IF(minimum_quantity OR stock, 0, 1)')
          ->order_by_asc('code')
          ->find_many();
?>
<script>
$(function() { 
var model= {
  product: <?=json_encode($product->as_array(),
                          JSON_PRETTY_PRINT|JSON_NUMERIC_CHECK)?>,
  items: [
<?
  /* Convert each row to an object */
  echo join(", \n",
            array_map(function ($items) {
                        return json_encode($items->as_array(),
                                           JSON_PRETTY_PRINT|
                                           JSON_NUMERIC_CHECK);
                      },
                      $items));
?>
  ],
  showInactive: <?=array_reduce($items, function ($c, $i) { return $c + $i->active; }) ? 0 : 1?>
};

var viewModel= ko.mapping.fromJS(model);

viewModel.toggleActive= function (item) {
  Scat.api('item-update',
           { id: item.id(),
             active: item.active() ? 0 : 1 })
      .done(function (data) {
        // XXX Doesn't re-sort the items
        ko.mapping.fromJS(data.item, {}, item);
      });
}

viewModel.toggleProductActive= function () {
  Scat.api('product-update',
           { id: viewModel.product.id(),
             active: viewModel.product.active() == '1' ? 0 : 1 })
      .done(function (data) {
        ko.mapping.fromJS(data, {}, viewModel.product);
      });
}

viewModel.editProduct= function (self) {
  Scat.dialog('product').done(function (html) {
    var panel= $(html);

    panel.on('hidden.bs.modal', function() {
      $(this).remove();
    });

    var product= ko.mapping.toJS(self.product);

    product.departments= [];
    product.brands= [];

    var panelModel= ko.mapping.fromJS(product);

    /* Load departments */
    Scat.api('department-find', { levels: 2 })
        .done(function (data) {
          ko.mapping.fromJS(data, {}, panelModel.departments);
          // make sure correct selection is made
          panelModel.department_id.valueHasMutated();
        });

    /* Load brands */
    Scat.api('brand-list', { verbose: 1 })
        .done(function (data) {
          ko.mapping.fromJS(data, {}, panelModel.brands);
          // make sure correct selection is made
          panelModel.brand_id.valueHasMutated();
        });

    panelModel.saveProduct= function(place, ev) {
      var product= ko.mapping.toJS(panelModel); /* XXX */
      delete product.departments;
      delete product.brands;

      Scat.api('product-update', product)
          .done(function (data) {
            $(place).closest('.modal').modal('hide');
            ko.mapping.fromJS(data, {}, viewModel.product);
          });
    }

    panelModel.generateSlug= function(place, ev) {
      Scat.api('generate-slug',
               { brand: panelModel.brand_id(), name: panelModel.name() })
          .done(function (data) {
            panelModel.slug(data.slug);
          })
    }

    panelModel.selectedDepartment= ko.computed({
      read: function () {
        return this.department_id();
      },
      write: function (value) {
        if (typeof value != 'undefined' && value != '') {
          this.department_id(value);
        }
      },
      owner: panelModel
    }).extend({ notify: 'always' });

    panelModel.selectedBrand= ko.computed({
      read: function () {
        return this.brand_id();
      },
      write: function (value) {
        if (typeof value != 'undefined' && value != '') {
          this.brand_id(value);
        }
      },
      owner: panelModel
    }).extend({ notify: 'always' });

    panel.html5Uploader({
      name: 'src',
      postUrl: function() { return 'api/image-add.php' },
      onSuccess: function(e, file, response) {
        data= $.parseJSON(response);
        if (data.error) {
          Scat.alert(data);
          return;
        }
        panelModel.image('/i/st/' + data.uuid + '.jpg');
      },
      onServerError: function(e, file) {
        Scat.alert("File upload failed.");
      },
    });

    ko.applyBindings(panelModel, panel[0]);
    panel.appendTo($('body')).modal();
  });
}

ko.applyBindings(viewModel);
});
</script>

<div class="pull-right well text-center">
  <label>
    <input type="checkbox" data-bind="checked: showInactive">
    Show inactive
  </label>
  <div>
    <button class="btn btn-primary"
            data-bind="click: editProduct">Edit</button>
  </div>
  <div>
    <button class="btn btn-xs btn-default"
            data-bind="click: toggleProductActive,
                       text: product.active() == '1' ? 'Active' : 'Inactive',
                       css: { 'btn-danger' : product.active() != '1' }">
    </button>
  </div>
</div>

{'fraction_non_alphanumeric': 0.1653061224489796, 'fraction_numerical': 0.0028182701652089406, 'mean_word_length': 2.0537091988130562, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3581033', 'n_tokens_mistral': 3144, 'n_tokens_neox': 3064, 'n_words': 594}