useTags = true; $this->commentsEnabled = true; parent::__construct($data, 'widgets'); $this->fullTextFields[] = 'name'; $this->fullTextFields[] = 'description'; $this->likeFields[] = 'name'; } public function getPagesXml() { $xml = parent::getPagesXml(); $xml .= << XML; return $xml; } public function initComponentsPage() { #$this->doCachePage = true; parent::initViewPage(); $this->kids = $this->getComponents(true); } public function drawComponentsPage() { if (count($this->kids)) { ?> kids AS $kid): ?> total(); ?> price(); ?> quantity): ?>
Part Unit Price Total
getName(true)?> quantity ?> @ getLink(".addsupplier?id=$kid->id", "add one")?>
Total:
No components needed.

'; } public function initUniquePartsPage() { #$this->doCachePage = true; if ($this->params('type') == 'json') parent::initJSONPage(); else parent::initViewPage(); $this->parts = array(); $this->determineUniqueParts($this->parts); } public function determineUniqueParts(&$parts) { if ($this->isRawPart()) $this->addUnique($parts); $kids = $this->getComponents(); if (count($kids)) foreach ($kids AS $kid){ $kid->determineUniqueParts($parts); } } public function isRawPart(){ $sup = $this->getSuppliers(); if (count($sup)){ $this->suppliers = $sup; return true; } } public function addUnique(&$parts) { if(!$parts[$this->id]) $parts[$this->id] = &$this; $parts[$this->id]->tot_quantity += $this->quantity; } public function drawUniquePartsPage() { $data = array(); foreach ($this->parts AS $part){ $data[$part->id] = $part->tot_quantity; } arsort($data); foreach ($data as $key => $qty) $names[$key] = $this->parts[$key]->getName(); asort($names); if ($this->params('type') == 'json') echo JSON::encode($data); else { ?> $name){ $qty = $data[$key]; echo " "; } echo ""; echo ""; echo "
Qty Part Links
$qty " . $this->parts[$key]->getName(false) . " Wiki - " . $this->parts[$key]->getLink(".view?id=$this->id", "Parts DB") . "
" . count($data) . "Unique Parts
" . array_sum($data) . "Total Parts
"; $form = $this->createGeoSupplierForm(); $form->drawIfNeeded(); } } public function createGeoSupplierForm() { $form = new Form(); $form->action = "http://" . $_SERVER['HTTP_HOST'] . $this->getUrl(".bomsuppliers?id=$this->id&bjtemplate=blank"); $form->add('CountryField', 'country', array( 'required' => true, 'title' => 'Find Suppliers in: ' )); $form->addSubmit('Go!'); return $form; } public function initBOMSuppliersPage() { parent::initViewPage(); $this->parts = array(); $this->determineUniqueParts($this->parts); $this->pageTitle = $_POST['country'][0] . " Suppliers for " . $this->getName(); } public function drawBOMSuppliersPage() { $data = array(); foreach ($this->parts AS $part){ $data[$part->id] = $part->tot_quantity; } arsort($data); foreach ($data as $key => $qty) $names[$key] = $this->parts[$key]->getName(); asort($names); ?> $name){ $qty = $data[$key]; echo " "; ?> "; echo "
$qty " . $this->parts[$key]->getName() . " Wiki - " . $this->parts[$key]->getLink(".view?id=$this->id", "Parts DB") . "
$priceM Supplier Name Buy Now!
getLink(".addsupplier?id=$key", "+ Add a New Supplier") ?>
 Unique Parts:" . count($data) . "
Total Parts:" . array_sum($data) . "
"; } public function initBillofMaterialsPage() { parent::initViewPage(); $this->needsJs("/js/dtree/dtree.js"); $this->needsCSS("/js/dtree/dtree.css"); $this->pageTitle = "Bill of Materials - " . $this->getName(); } public function drawBillofMaterialsPage() { ?>

Welcome, this page is where you can generate a bill of materials for any component in the project. To make this as easy and interactive as possible, on this page you'll be able to choose from a variety of options to create your parts list. Then you will be able to print it for future reference.

Directions:

  1. Select Desired Parts (some parts have alternative parts that may be cheaper / easier to aquire for you)
  2. Select Country (some suppliers only ship to certain countries or are cheaper for a certain country)
  3. Select Suppliers (you will save money by going through fewer suppliers)
  4. Generate List (we will then generate you a parts list which you can print off or save)
Loading...
quantity * $this->price(); } public function price() { $rs = dbQuery(" SELECT sp.id, s.name FROM supplier_parts sp INNER JOIN suppliers s ON sp.supplier_id = s.id WHERE sp.widget_id = '$this->id' ORDER BY sp.price ASC LIMIT 1"); $ar = mysql_fetch_assoc($rs); $ob = new SupplierPart($ar['id']); $ob->supplier = $ar['name']; if ($ob->price) return $ob->price; else { $kids = $this->getComponents(); if (count($kids)){ foreach ($kids AS $kid) $total += $kid->price() * $kid->quantity; return $total; } else return null; } } public function getBestSuppliers() { } public function getSuppliers() { $om = new SupplierParts(); return $om->search(array( "widget_id" => $this->id )); } public function getAlternatives() { $om = new Widgets(); return $om->search(array( "alternative" => $this->id )); } public function getComponents($full = false) { $rs = dbQuery(" SELECT w2w.quantity, w2w.unit, w.* FROM widgets w INNER JOIN widgets_to_widgets w2w ON w.id = w2w.child_id WHERE w2w.parent_id = '$this->id' ORDER BY w.name "); while ($ar = mysql_fetch_assoc($rs)) { $ob = new Widget($ar['id']); $ob->quantity = $ar['quantity']; $ob->unit = $ar['unit']; if ($full) $ob->kids = $ob->getComponents($full); $kids[] = $ob; } return $kids; } public function delete() { dbExecute(" DELETE FROM widgets_to_widgets WHERE parent_id = '$this->id' OR child_id = '$this->id' "); dbExecute(" DELETE FROM widgets_to_alternatives WHERE widget_id = '$this->id' OR alternative_id = '$this->id' "); $steps = new Steps(); $rs = $steps->search(array( 'widget_id' => $this->id )); foreach ($rs As $ob) $ob->delete(); parent::delete(); } public function initPublishPage() { parent::initEditPage(); $this->pageTitle = 'Publish Widget - ' . $this->getName(); } public function initSetQtyPage() { parent::initEditPage(); $this->setTemplate(new BlankTemplate()); } public function drawSetQtyPage() { $qty = $this->params("qty"); $unit = $this->params("unit"); $parent_id = $this->id; $child_id = $this->params('part_id'); dbQuery(" UPDATE widgets_to_widgets SET quantity = '$qty', unit = '$unit' WHERE parent_id = '$parent_id' AND child_id = '$child_id' "); echo $qty; } public function drawPublishPage() { $this->publish(); echo "You widget '" . $this->getName(true) . "' has been published."; } public function publish() { $this->is_published = true; $this->save(); $kids = $this->getComponents(false); if (count($kids)){ foreach ($kids AS $kid){ $kid->publish(); } } } public function initEditStepsPage() { parent::initEditPage(); $this->pageTitle = 'Edit Steps - ' . $this->getName(); } public function drawEditStepsPage() { $links[] = $this->getLink(".view?id=$this->id", "Back to " . $this->getName()); $links[] = $this->getLink("step.edit?widget_id=$this->id", "Add New Step"); $this->drawPageNavigation($links); echo "

Click name and drag to re-order steps. The first step image will be the widget image.

"; $steps = new Steps(); $rs = $steps->search(array( 'widget_id' => $this->id )); if (count($rs)) { ?>
    id\">"; echo $ob->getName(false); echo " " . $ob->getLink(".view?id=$ob->id", "view"); echo " " . $ob->getLink(".edit?id=$ob->id", "edit"); echo " " . $ob->getLink(".editimages?id=$ob->id", "images"); echo " " . $ob->getLink(".delete?id=$ob->id", "delete"); echo ""; } ?>
No Steps Found.

"; } public function initEditPartsPage() { parent::initEditPage(); $this->pageTitle = 'Edit Parts - ' . $this->getName(); } public function drawEditPartsPage() { $links[] = $this->getLink(".view?id=$this->id", "Back to " . $this->getName()); $links[] = $this->getLink(".addpart?id=$this->id&type=child", "Add Component"); $links[] = $this->getLink(".addsupplier?id=$this->id", "Add Supplier"); $links[] = $this->getLink(".addpart?id=$this->id&type=alternative", "Add Alternative Part"); $this->drawPageNavigation($links); $rs = $this->getComponents(); echo "

Child Parts

"; if (count($rs)) { ?>
Name QTY / Units Manage
getName(true);?> getLink(".view?id=$ob->id", "view"); ?> getLink(".edit?id=$ob->id", "edit"); ?> getLink(".removepart?id=$this->id&part_id=$ob->id&type=child", "remove"); ?>
No Parts Found."; echo "

"; $rs = $this->getAlternatives(); echo "

Alternative Parts

"; if (count($rs)) { echo ""; foreach ($rs AS $ob) { echo ""; } echo "
"; echo $ob->getName(false); echo ""; if ($ob->canView()) echo " " . $ob->getLink(".view?id=$ob->id", "view"); if ($ob->canEdit()) echo " " . $ob->getLink(".edit?id=$ob->id", "edit"); if ($this->canEdit()) echo " " . $ob->getLink(".removepart?id=$this->id&part_id=$ob->id&type=alternative", "remove"); echo "
"; } else echo "No Parts Found."; echo "

"; } public function initEditSuppliersPage() { parent::initEditPage(); $this->pageTitle = 'Edit Suppliers - ' . $this->getName(); } public function drawEditSuppliersPage() { $links[] = $this->getLink(".view?id=$this->id", "Back to " . $this->getName()); $links[] = $this->getLink(".addsupplier?id=$this->id", "Add Supplier"); $links[] = $this->getLink(".addpart?id=$this->id&type=child", "Add Component"); $this->drawPageNavigation($links); $parts = new SupplierParts(); $rs = $parts->search(array( 'widget_id' => $this->id )); echo "

Suppliers

"; if (count($rs)) { echo ""; foreach ($rs AS $ob) { $supplier = new Supplier($ob->supplier_id); echo ""; } echo "
"; echo $supplier->getName(false); echo " ($ob->price)"; echo ""; if ($ob->canView()) echo " " . $ob->getLink(".view?id=$ob->id", "view"); if ($ob->canEdit()) echo " " . $ob->getLink(".edit?id=$ob->id", "edit"); if ($this->canEdit()) echo " " . $ob->getLink(".delete?id=$ob->id", "remove"); echo "
"; } else echo "No Suppliers Found."; echo "

"; } public function initAddSupplierPage() { parent::initEditPage(); $this->pageTitle = 'Add Supplier to ' . $this->getName(); } public function drawAddSupplierPage() { global $me; $form = $this->createAddSupplierForm(); if ($form->isSubmitted()) { $form->validate(); if (!$form->hasError()) { $supplierId = (int)$form->getData('supplier_id'); //did we get the part? if ($supplierId) $supplier = new Supplier($supplierId); //either create a new one, also double check its real. if (!$supplierId || $supplier->name != $_POST['supplier_id_search']) { $newSupplier = true; //set up our stuff $supplier = new Supplier(); $supplier->name = dbEscape($_POST['supplier_id_search']); $supplier->user_id = $me->id; $supplier->add_date = date("Y-m-d H:i:s"); $supplier->edit_date = date("Y-m-d H:i:s"); $supplier->save(); } //make sure we have a supplier id. if ($supplier->id) { //create the part entry $part = new SupplierPart(); $part->user_id = $me->id; $part->supplier_id = $supplier->id; $part->widget_id = $this->id; $part->add_date = date("Y-m-d H:i:s"); $part->edit_date = date("Y-m-d H:i:s"); $part->price_date = date("Y-m-d H:i:s"); $part->price = $form->getData('price'); $part->detail_link = $form->getData('detail_link'); $part->approved = 1; $part->save(); if ($newSupplier) Util::redirect($supplier->getUrl(".edit?id=$supplier->id")); else Util ::redirect($this->getUrl(".editsuppliers?id=$this->id")); } else throw new PageError("Something went wrong."); } } $form->drawIfNeeded(); } public function createAddSupplierForm() { $form = new Form(); $form->action = $this->getUrl(".addsupplier?id=$this->id"); $form->add('AutoCompleteIdField', 'supplier_id', array( 'width' => '85%', 'title' => 'Supplier Name', 'lookupUrl' => $this->getUrl("suppliers.search?output=autocomplete") )); $form->add('TextField', 'detail_link', array( 'title' => 'Detail / Buy URL', 'width' => '85%' )); $form->add('TextField', 'price', array( )); $form->addSubmit('Add Supplier'); return $form; } public function initAddPartPage() { parent::initEditPage(); $this->pageTitle = 'Add Part to ' . $this->getName(); } public function drawAddPartPage() { global $me; $form = $this->createAddPartForm($this->params('type')); if ($form->isSubmitted()) { $form->validate(); $partId = (int)$form->getData('part_id'); //did we get the part? if ($partId) $part = new Widget($partId); //nope, create it. else { //set up our stuff $part = new Widget(); $part->user_id = $me->id; $part->name = dbEscape($_POST['part_id_search']); $part->add_date = date("Y-m-d H:i:s"); $part->edit_date = date("Y-m-d H:i:s"); $part->save(); } if ($part->id == $this->id) $form->setError('part', "The widget cannot have a part that is itself"); if (!$form->hasError()) { //make sure we have a part id. if ($part->id) { if ($this->params('type') == 'child') $this->addChildPart($part->id, $form->getData('quantity'), $form->getData('units'), $form->getData('notes')); else $this->addAlternativePart($part->id, $form->getData('notes')); Util::redirect($this->getUrl(".editparts?id=$this->id")); } else throw new PageError("Something went wrong."); } } $form->drawIfNeeded(); } public function createAddPartForm($type) { $form = new Form(); $form->action = $this->getUrl(".addpart?id=$this->id&type=$type"); $form->add('AutoCompleteIdField', 'part_id', array( 'width' => '100%', 'title' => 'Part Name', 'lookupUrl' => $this->getUrl("widgets.search?output=autocomplete") )); if ($type == 'child') { $form->add('TextField', 'quantity', array( 'required' => true, 'width' => '40px' )); $form->add('TextField', 'units', array( 'width' => '100px', 'title' => 'Units (item, cc, mm, oz, etc.)' )); $form->add('TextareaField', 'notes', array( 'width' => '100%', 'height' => '80px', 'title' => 'Notes' )); $form->addSubmit('Add Child Part'); } else { $form->add('TextareaField', 'notes', array( 'width' => '100%', 'height' => '80px', 'title' => 'Notes' )); $form->addSubmit('Add Alternative Part'); } return $form; } public function initRemovePartPage() { parent::initEditPage(); $this->pageTitle = 'Remove Part From ' . $this->getName(); } public function drawRemovePartPage() { if ($this->params('type') == 'child') $this->removeChildPart($this->params('part_id')); else $this->removeAlternativePart($this->params('part_id')); Util::redirect($this->getUrl(".editparts?id=$this->id")); } public function addChildPart($id, $quantity, $unit, $notes = '') { $quantity = (int)$quantity; $unit = dbEscape($unit); $notes = dbEscape($notes); dbExecute(" INSERT INTO widgets_to_widgets (parent_id, child_id, quantity, unit, notes) VALUES ('$this->id', '$id', '$quantity', '$unit', '$notes') "); } public function addAlternativePart($id, $notes = '') { $notes = dbEscape($notes); dbExecute(" INSERT INTO widgets_to_alternatives (widget_id, alternative_id, notes) VALUES ('$this->id', '$id', '$notes') "); } public function removeChildPart($id) { dbExecute(" DELETE FROM widgets_to_widgets WHERE parent_id = '$this->id' AND child_id = '$id' "); } public function removeAlternativePart($id) { dbExecute(" DELETE FROM widgets_to_alternatives WHERE widget_id = '$this->id' AND alternative_id = '$id' "); } public function getCreateFieldsArray() { $data = parent::getCreateFieldsArray(); $data['name'] = "name varchar(255) default '' not null"; $data['description'] = "description text default '' not null"; $data['image_id'] = 'image_id int(11) default 0 not null'; $data['is_published'] = 'is_published tinyint(1) default 0 not null'; $data['website'] = "website varchar(255) default '' not null"; $data['svn_repository'] = "svn_repository varchar(255) default '' not null"; return $data; } public function getCreateIndexesArray() { $data = parent::getCreateIndexesArray(); $data['image_id'] = 'key(image_id)'; return $data; } public function editFormAddFields($form) { global $me; if ($this->id) $form->add('CheckboxField', 'is_published', array('label' => 'Is Published?')); if ($me->isAdmin()) $form->add('CheckBoxField', 'featured', array('label' => 'Is Featured?')); $form->add('CheckboxField', 'can_be_fabricated', array('label' => 'Can it be fabricated?')); $form->add('TextField', 'name', array( 'required' => true, 'width' => '100%', )); $form->add('TextAreaField', 'description', array( 'width' => '100%', 'height' => '150px' )); $form->add('TextField', 'website', array( 'width' => '100%', )); $form->add('TextField', 'svn_repository', array( 'width' => '100%', 'title' => 'SVN Url' )); $form->add('TextField', 'flickr_set_id', array( 'width' => '100%', 'title' => 'Flickr SetID or Set URL' )); $form->add('TextField', 'video_link', array( 'width' => '100%', 'title' => 'Vimeo video URL / ID
(YouTube works too)' )); $this->tags->addTagFields($form); if ($this->id) $form->addSubmit('Save Widget'); else $form->addSubmit('Add Widget'); } public function getName($link = false) { return parent::getName($link, $this->name); } public function initViewPage() { parent::initViewPage(); if (!$this->isPublished()) $this->addStatus("This widget is not published. getUrl(".publish?id=$this->id") . "\" onclick=\"return Widget.publish($this->id)\">Publish Now!" ); ob_start(); ?>

Meta Data

Creator: creator->getName(true);?>
Added: add_date, false);?>
Updated: edit_date, false);?>

Links

website) echo "website\">Part Homepage
"; if ($this->svn_repository) echo "svn_repository\">SVN Repository
"; echo "

"; ?> --> parts = new Widgets(); $rs = $this->parts->search(array( 'child_id' => $this->id )); if (count($rs)) { echo "

I am part of:

"; foreach ($rs AS $ob) $data[] = $ob->getName(true); echo implode(", ", $data); echo "

"; } //draw my tags $this->tagFactory(); $tags = $this->tags->getTags(); if (count($tags)) echo "

Tags (" . $this->tags->getLink(".main", "popular") . ")

" . $this->tags->getTagList($tags) . "

"; $this->SidebarData = ob_get_contents(); ob_end_clean(); } public function getWikiUrl() { if ($this->wiki_url == '') return "http://objects.reprap.org/mediawiki/index.php/" . preg_replace('/\W/', '', $this->getName()); else return $this->wiki_url; } public function drawViewPage() { if ($this->canEdit()) { $links[] = $this->getLink(".edit?id=$this->id", "Edit Part"); $links[] = $this->getLink(".editparts?id=$this->id", "Edit Components"); $links[] = $this->getLink(".editsuppliers?id=$this->id", "Edit Suppliers"); $links[] = $this->getLink(".delete?id=$this->id", "Delete Part"); } if (count($links)) $this->drawPageNavigation($links); $wiki = "Wiki"; $comps = $this->getComponents(); $suppliers = $this->getSuppliers(); $alts = $this->getAlternatives(); ?>

description)?>

getUrl(".components?id=$this->id&bjtemplate=blank"); ?> getUrl("supplierparts.search?widget_id=$this->id&bjtemplate=blank") ?> getUrl("widgets.search?alternative=$this->id&bjtemplate=blank") ?>
getUrl("widgetthread.main?content_id=$this->id&bjtemplate=blank") ?> id");?>" onclick="return Widget.load('');" >Comments (comment_count?>)
media_link)) return $this->getVimeoEmbed($this->media_link); else if (preg_match("/youtube\.com/", $this->media_link)) return $this->getYouTubeEmbed($this->media_link); else if (preg_match("/flickr\.com/", $this->media_link)) return $this->getFlickrEmbed($this->media_link); } public function getFlickrEmbed($link){ if (preg_match("/\d{4,}/", $link, $matches)) return ""; } public function getVimeoEmbed($link){ if (preg_match("/[0-9]{3,}/", $link, $matches)) return ""; } public function getYouTubeEmbed($link){ if (preg_match("/[0-9a-zA-Z]{3,}$/", $link, $matches)) return ''; } public function drawRow() { ?> getName(true)?> isPublished()): ?> -- Not Published!
doCachePage = true; parent::initJSONPage(); } public function initXMLPage() { $this->doCachePage = true; parent::initXMLPage(); } public function initPHPPage() { $this->doCachePage = true; parent::initPHPPage(); } public function isPublished() { return (bool)$this->is_published; } public function getPublicData() { $data = parent::getPublicData(); //load some basic stuff. $data['name'] = $this->getName(); $data['description'] = Linkify::bbcode($this->description); $data['is_published'] = $this->is_published; $data['website'] = $this->website; $datap['svn_repository'] = $this->svn_repository; $data['can_be_fabricated'] = $this->can_be_fabricated; $data['featured'] = $this->featured; $data['media_link'] = $this->media_link; $data['media_embed'] = $this->getMediaEmbedMarkup(); $kids = $this->getComponents(false); if (count($kids)){ foreach ($kids AS $kid) $data['components'][] = $kid->getPublicData(); } $kids = $this->getSuppliers(false); if (count($kids)){ foreach ($kids AS $kid) $data['suppliers'][] = $kid->getPublicData(); } /* $alts = $this->getAlternatives(); if (count($alts)){ foreach ($alts AS $alt){ $data['alternatives'][] = $alt->getPublicData(); } } */ return $data; } public function getRssItem() { $item = parent::getRssItem(); $item->title = $this->getName(true); $item->description = Linkify::bbcode($this->description); return $item; } public function getCreateTableSql() { $sql = parent::getCreateTableSql(); $sql .= " CREATE TABLE widgets_to_widgets ( parent_id int(11) default 0 not null, child_id int(11) default 0 not null, quantity int(11) default 0 not null, key(parent_id), key(child_id) ); CREATE TABLE widgets_to_alternatives ( widget_id int(11) default 0 not null, alternative_id int(11) default 0 not null, key(widget_id), key(alternative_id) ); "; return $sql; } } class WidgetThread extends BaseThread { function __construct($contentId = null) { parent::__construct($contentId, 'Widget'); } } class WidgetComment Extends BaseComment { function __construct($data = null) { parent::__construct($data, 'widget'); } } ?>