├── README.markdown ├── mongo.css ├── mongoDB_Banner.png └── mongodbadmin.php /README.markdown: -------------------------------------------------------------------------------- 1 | # PHP MongoDB Admin 2 | 3 | ## THIS REPOSITORY IS NO LONGER ACTIVELY MAINTAINED OR SUPPORTED 4 | 5 | A MongoDB Admin interface that runs in your web browser. 6 | 7 | Open mongodbadmin.php in your browser and have a look! 8 | -------------------------------------------------------------------------------- /mongo.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* CSS Document */ 3 | 4 | html{color:#000;background:#FFF;} 5 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;color:#666;} 6 | table{border-collapse:collapse;border-spacing:0;} 7 | fieldset,img{border:0;} 8 | address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;} 9 | li{list-style:none;} 10 | caption,th{text-align:left;} 11 | h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;} 12 | q:before,q:after{content:'';} 13 | abbr,acronym{border:0;font-variant:normal;} 14 | sup{vertical-align:text-top;} 15 | sub{vertical-align:text-bottom;} 16 | input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;} 17 | input,textarea,select{*font-size:100%;} 18 | legend{color:#000;} 19 | html { background: #666; font:13px/1.231 "Lucida Grande",verdana,arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;} 20 | table {font-size:inherit;font:100%;} 21 | pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;} 22 | a:link, a:visited, a:active { text-decoration:none; color:#666; outline:none; border:0; } 23 | a:hover { color:#F90; text-decoration:none; border:0; } 24 | 25 | pre { 26 | -moz-border-radius: 10px; 27 | -webkit-border-radius: 10px; 28 | border-radius: 10px; 29 | padding: 10px; 30 | background-color: #222; 31 | overflow/**/: auto; 32 | margin-bottom: 15px; 33 | line-height: 17px; 34 | font-size: 13px; 35 | color: #fff; 36 | font-family: "Bitstream Vera Sans Mono", monospace; 37 | white-space: pre-wrap; 38 | } 39 | 40 | pre a { 41 | color: #fff !important; 42 | text-decoration: underline !important; 43 | } 44 | 45 | #content { 46 | -moz-border-radius: 10px; 47 | -webkit-border-radius: 10px; 48 | border-radius: 10px; 49 | margin-top: 20px; 50 | margin-bottom: 20px; 51 | padding: 20px; 52 | width: 90%; 53 | margin-left: auto; 54 | margin-right: auto; 55 | position:relative; 56 | background:#FFF; 57 | color: #495a7e; 58 | } 59 | #content h1 { font-size: 20px; font-weight: bold; margin-bottom: 15px; color:#FBDDA4; } 60 | #content h2 { font-size: 14px; font-weight: bold; margin-bottom: 15px; margin-top: 10px; color:#5AAC41; } 61 | 62 | #footer { 63 | margin-top: 15px; 64 | text-align: center; 65 | font-weight: bold; 66 | font-size: 10px; 67 | color:#FFF; 68 | } 69 | 70 | #create_form { 71 | -moz-border-radius: 10px; 72 | -webkit-border-radius: 10px; 73 | border-radius: 10px; 74 | padding: 15px; 75 | background: #5AAC41; 76 | width: 400px; 77 | float: right; 78 | margin-bottom: 10px; 79 | } 80 | #create_form label { 81 | float: left; 82 | padding: 4px; 83 | font-weight: bold; 84 | margin-right: 10px; 85 | color:#FFF; 86 | } 87 | #pager { 88 | -moz-border-radius: 10px; 89 | -webkit-border-radius: 10px; 90 | border-radius: 10px; 91 | background: #f5f5f5; 92 | padding: 8px; 93 | margin-bottom: 15px; 94 | width: 350px; 95 | float: left; 96 | } 97 | #search { 98 | -moz-border-radius: 10px; 99 | -webkit-border-radius: 10px; 100 | border-radius: 10px; 101 | background: #F90; 102 | padding: 8px; 103 | margin-bottom: 15px; 104 | width: 500px; 105 | float: right; 106 | } 107 | #mongoLogo{ 108 | background-image:url(mongoDB_Banner.png); 109 | background-repeat:no-repeat; 110 | width:200px; 111 | height:75px; 112 | float:left; 113 | margin-left:-32px; 114 | } 115 | table { 116 | background: #000; 117 | -moz-border-radius: 10px; 118 | -webkit-border-radius: 10px; 119 | border-radius: 10px; 120 | border-collapse: collapse; 121 | width: 100%; 122 | } 123 | table th { 124 | color: #fff; 125 | font-weight: bold; 126 | padding: 8px; 127 | } 128 | table td { 129 | padding: 8px; 130 | } 131 | table td a { 132 | font-weight: bold; 133 | } 134 | table tbody tr { 135 | background-color: #F3F4EB; 136 | border-bottom: 1px solid #ccc; 137 | } 138 | table tbody tr:hover { 139 | background-color: #333; 140 | } 141 | .save_button { 142 | -moz-border-radius: 10px; 143 | -webkit-border-radius: 10px; 144 | border-radius: 10px; 145 | background-color: #F90; 146 | color: #fff; 147 | padding: 4px; 148 | font-weight: bold; 149 | padding-left: 10px; 150 | padding-right: 10px; 151 | } 152 | .save_button:hover { 153 | background-color: #ccc; 154 | color: #333; 155 | cursor: pointer; 156 | } 157 | textarea { 158 | padding: 10px; 159 | -moz-border-radius: 10px; 160 | -webkit-border-radius: 10px; 161 | border-radius: 10px; 162 | border: 1px solid #ccc; 163 | width: 100%; 164 | height: 350px; 165 | margin-top: 10px; 166 | margin-bottom: 10px; 167 | } 168 | .footer{color:#CCC;} -------------------------------------------------------------------------------- /mongoDB_Banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwage/php-mongodb-admin/2f3b703db24754d4045941c88d297493f83d3b57/mongoDB_Banner.png -------------------------------------------------------------------------------- /mongodbadmin.php: -------------------------------------------------------------------------------- 1 | 18 | * @Theme Ted Veatch 19 | */ 20 | 21 | header('Pragma: no-cache'); 22 | 23 | $server = array( 24 | 'mongodb://localhost:27017', 25 | // 'mongodb://example.org:27017', 26 | ); 27 | 28 | $options = array( 29 | 'connect' => true 30 | ); 31 | 32 | $readOnly = false; 33 | 34 | if (!class_exists('MongoClient')) 35 | { 36 | die("Mongo support required. Install mongo pecl extension with 'pecl install mongo; echo \"extension=mongo.so\" >> php.ini'"); 37 | } 38 | try 39 | { 40 | $mongo = new MongoClient(getServer($server), $options); 41 | } 42 | catch (MongoConnectionException $ex) 43 | { 44 | error_log($ex->getMessage()); 45 | die("Failed to connect to MongoDB"); 46 | } 47 | 48 | 49 | /** 50 | * Get the current MongoDB server. 51 | * 52 | * @param mixed $server 53 | * @return string $server 54 | */ 55 | function getServer($server) 56 | { 57 | if (is_array($server)) { 58 | return (isset($_COOKIE['mongo_server']) && isset($server[$_COOKIE['mongo_server']])) ? $server[$_COOKIE['mongo_server']] : $server[0]; 59 | } else { 60 | return $server; 61 | } 62 | } 63 | 64 | /** 65 | * Render a document preview for the black code box with referenced 66 | * linked to the collection and id for that database reference. 67 | * 68 | * @param string $document 69 | * @return string $preview 70 | */ 71 | function renderDocumentPreview($mongo, $document) 72 | { 73 | $document = prepareMongoDBDocumentForEdit($document); 74 | $preview = linkDocumentReferences($mongo, $document); 75 | $preview = print_r($preview, true); 76 | return $preview; 77 | } 78 | 79 | /** 80 | * Change any references to other documents to include a html link 81 | * to that document and collection. Used by the renderDocumentPreview() function. 82 | * 83 | * @param array $document 84 | * @return array $document 85 | */ 86 | function linkDocumentReferences($mongo, $document) 87 | { 88 | foreach ($document as $key => $value) { 89 | if (is_array($value)) { 90 | if (isset($value['$ref'])) { 91 | $collection = $mongo->selectDB($_REQUEST['db'])->selectCollection($value['$ref']); 92 | $id = $value['$id']; 93 | 94 | $ref = findMongoDbDocument($value['$id'], $_REQUEST['db'], $value['$ref']); 95 | if (!$ref) { 96 | $ref = findMongoDbDocument($value['$id'], $_REQUEST['db'], $value['$ref'], true); 97 | } 98 | 99 | $refDb = isset($value['$db']) ? $value['$db'] : $_REQUEST['db']; 100 | 101 | $document[$key]['$ref'] = ''.$value['$ref'].''; 102 | 103 | if ($ref['_id'] instanceof MongoId) { 104 | $document[$key]['$id'] = ''.$value['$id'].''; 105 | } else { 106 | $document[$key]['$id'] = ''.$value['$id'].''; 107 | } 108 | 109 | if (isset($value['$db'])) { 110 | $document[$key]['$db'] = ''.$refDb.''; 111 | } 112 | } else { 113 | $document[$key] = linkDocumentReferences($mongo, $value); 114 | } 115 | } 116 | } 117 | return $document; 118 | } 119 | 120 | /** 121 | * Prepare user submitted array of PHP code as a MongoDB 122 | * document that can be saved. 123 | * 124 | * @param mixed $value 125 | * @return array $document 126 | */ 127 | function prepareValueForMongoDB($value) 128 | { 129 | $customId = isset($_REQUEST['custom_id']); 130 | 131 | if (is_string($value)) { 132 | $value = preg_replace('/\'_id\' => \s*MongoId::__set_state\(array\(\s*\)\)/', '\'_id\' => new MongoId("' . (isset($_REQUEST['id']) ? $_REQUEST['id'] : '') . '")', $value); 133 | $value = preg_replace('/MongoId::__set_state\(array\(\s*\)\)/', 'new MongoId()', $value); 134 | $value = preg_replace('/MongoDate::__set_state\(array\(\s*\'sec\' => (\d+),\s*\'usec\' => \d+,\s*\)\)/m', 'new MongoDate($1)', $value); 135 | $value = preg_replace('/MongoBinData::__set_state\(array\(\s*\'bin\' => \'(.*?)\',\s*\'type\' => ([1,2,3,5,128]),\s*\)\)/m', 'new MongoBinData(\'$1\', $2)', $value); 136 | 137 | eval('$value = ' . $value . ';'); 138 | 139 | if (!$value) { 140 | header('location: ' . $_SERVER['HTTP_REFERER'] . ($customId ? '&custom_id=1' : null)); 141 | exit; 142 | } 143 | } 144 | 145 | $prepared = array(); 146 | foreach ($value as $k => $v) { 147 | if ($k === '_id' && !$customId) { 148 | $v = new MongoId($v); 149 | } 150 | 151 | if ($k === '$id' && !$customId) { 152 | $v = new MongoId($v); 153 | } 154 | 155 | if (is_array($v)) { 156 | $prepared[$k] = prepareValueForMongoDB($v); 157 | } else { 158 | $prepared[$k] = mysqli_real_escape_string($v); 159 | } 160 | } 161 | return $prepared; 162 | } 163 | 164 | /** 165 | * Prepare a MongoDB document for the textarea so it can be edited. 166 | * 167 | * @param array $value 168 | * @return array $prepared 169 | */ 170 | function prepareMongoDBDocumentForEdit($value) 171 | { 172 | $prepared = array(); 173 | foreach ($value as $key => $value) { 174 | if ($key === '_id') { 175 | $value = (string) $value; 176 | } 177 | if ($key === '$id') { 178 | $value = (string) $value; 179 | } 180 | if (is_array($value)) { 181 | $prepared[$key] = prepareMongoDBDocumentForEdit($value); 182 | } else { 183 | $prepared[$key] = $value; 184 | } 185 | } 186 | return $prepared; 187 | } 188 | 189 | /** 190 | * Search for a MongoDB document based on the id 191 | * 192 | * @param string $id The ID to search for 193 | * @param string $db The db to use 194 | * @param string $collection The collection to search in 195 | * @param bool $forceCustomId True to force a custom id search 196 | * @return mixed $document 197 | * 198 | */ 199 | function findMongoDbDocument($id, $db, $collection, $forceCustomId = false) 200 | { 201 | global $mongo; 202 | 203 | $collection = $mongo->selectDB($db)->selectCollection($collection); 204 | 205 | if (isset($_REQUEST['custom_id']) || $forceCustomId) { 206 | if (is_numeric($id)) { 207 | $id = (int) $id; 208 | } 209 | $document =$collection->findOne(array('_id' => $id)); 210 | } else { 211 | $document = $collection->findOne(array('_id' => new MongoId($id))); 212 | } 213 | 214 | return $document; 215 | } 216 | 217 | // Actions 218 | try { 219 | // SEARCH BY ID 220 | if (isset($_REQUEST['search']) && !is_object(json_decode($_REQUEST['search']))) { 221 | $customId = false; 222 | $document = findMongoDbDocument($_REQUEST['search'], $_REQUEST['db'], $_REQUEST['collection']); 223 | 224 | if (!$document) { 225 | $document = findMongoDbDocument($_REQUEST['search'], $_REQUEST['db'], $_REQUEST['collection'], true); 226 | $customId = true; 227 | } 228 | 229 | if (isset($document['_id'])) { 230 | $url = $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['db']) . '&collection=' . $_REQUEST['collection'] . '&id=' . (string) $document['_id']; 231 | 232 | if ($customId) { 233 | header('location: ' . $url . '&custom_id=true'); 234 | } else { 235 | header('location: ' . $url); 236 | } 237 | } 238 | } 239 | 240 | // DELETE DB 241 | if (isset($_REQUEST['delete_db']) && $readOnly !== true) { 242 | $mongo 243 | ->selectDB($_REQUEST['delete_db']) 244 | ->drop(); 245 | 246 | header('location: ' . $_SERVER['PHP_SELF']); 247 | exit; 248 | } 249 | 250 | // CREATE DB 251 | if (isset($_REQUEST['create_db']) && $readOnly !== true) { 252 | $mongo->selectDB($_REQUEST['create_db'])->createCollection('__tmp_collection_'); 253 | $mongo->selectDB($_REQUEST['create_db'])->dropCollection('__tmp_collection_'); 254 | 255 | header('location: ' . $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['create_db'])); 256 | exit; 257 | 258 | } 259 | 260 | // CREATE DB COLLECTION 261 | if (isset($_REQUEST['create_collection']) && $readOnly !== true) { 262 | $mongo 263 | ->selectDB($_REQUEST['db']) 264 | ->createCollection($_REQUEST['create_collection']); 265 | 266 | header('location: ' . $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['db']) . '&collection=' . $_REQUEST['create_collection']); 267 | exit; 268 | } 269 | 270 | // DELETE DB COLLECTION 271 | if (isset($_REQUEST['delete_collection']) && $readOnly !== true) { 272 | $mongo 273 | ->selectDB($_REQUEST['db']) 274 | ->selectCollection($_REQUEST['delete_collection']) 275 | ->drop(); 276 | 277 | header('location: ' . $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['db'])); 278 | exit; 279 | } 280 | 281 | // DELETE DB COLLECTION DOCUMENT 282 | if (isset($_REQUEST['delete_document']) && $readOnly !== true) { 283 | $collection = $mongo->selectDB($_REQUEST['db'])->selectCollection($_REQUEST['collection']); 284 | 285 | if (isset($_REQUEST['custom_id'])) { 286 | $id = $_REQUEST['delete_document']; 287 | if (is_numeric($id)) { 288 | $id = (int) $id; 289 | } 290 | $collection->remove(array('_id' => $id)); 291 | } else { 292 | $collection->remove(array('_id' => new MongoId($_REQUEST['delete_document']))); 293 | } 294 | 295 | header('location: ' . $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['db']) . '&collection=' . $_REQUEST['collection']); 296 | exit; 297 | } 298 | 299 | // DELETE DB COLLECTION DOCUMENT FIELD AND VALUE 300 | if (isset($_REQUEST['delete_document_field']) && $readOnly !== true) { 301 | $coll = $mongo 302 | ->selectDB($_REQUEST['db']) 303 | ->selectCollection($_REQUEST['collection']); 304 | 305 | $document = findMongoDbDocument($_REQUEST['id'], $_REQUEST['db'], $_REQUEST['collection']); 306 | unset($document[$_REQUEST['delete_document_field']]); 307 | $coll->save($document); 308 | 309 | $url = $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['db']) . '&collection=' . $_REQUEST['collection'] . '&id=' . (string) $document['_id']; 310 | header('location: ' . $url); 311 | exit; 312 | } 313 | 314 | // INSERT OR UPDATE A DB COLLECTION DOCUMENT 315 | if (isset($_POST['save']) && $readOnly !== true) { 316 | $customId = isset($_REQUEST['custom_id']); 317 | $collection = $mongo->selectDB($_REQUEST['db'])->selectCollection($_REQUEST['collection']); 318 | 319 | $document = prepareValueForMongoDB($_REQUEST['value']); 320 | $collection->save($document); 321 | 322 | $url = $_SERVER['PHP_SELF'] . '?db=' . urlencode($_REQUEST['db']) . '&collection=' . $_REQUEST['collection'] . '&id=' . (string) $document['_id']; 323 | header('location: ' . $url . ($customId ? '&custom_id=1' : null)); 324 | exit; 325 | } 326 | 327 | // Catch any errors and redirect to referrer with error 328 | } catch (Exception $e) { 329 | header('location: '.$_SERVER['HTTP_REFERER'].'&error='.htmlspecialchars($e->getMessage())); 330 | exit; 331 | } 332 | ?> 333 | 334 | 335 | 336 | PHP MongoDB Admin 337 | 358 | 359 | 360 | 361 | 362 | 363 | 364 |
365 |

366 | 367 | 368 | 1): ?> 369 | 374 | 375 | 376 | 377 | 378 | 379 | 380 |

381 | 382 |
383 | 384 |
385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 |
394 |
395 | 396 | 397 | 398 |
399 |
400 | 401 | 402 |

Databases

403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | listDBs() ?> 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 |
NameCollections
selectDb($db['name'])->listCollections()) ?>Delete 
428 | 429 | 430 | 431 | 432 | 433 |
434 |
435 | 436 | 437 | 438 |
439 |
440 | 441 | 442 |

443 | Databases >> 444 | 445 |

446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | selectDB($_REQUEST['db'])->listCollections() ?> 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 |
Collection NameDocuments
getName() ?>count(); ?>Delete 
470 | 471 | 472 | 473 | 474 | selectDB($_REQUEST['db']) 485 | ->selectCollection($_REQUEST['collection']) 486 | ->find($search) 487 | ->limit($limit) 488 | ->skip($skip); 489 | } else { 490 | $cursor = $mongo 491 | ->selectDB($_REQUEST['db']) 492 | ->selectCollection($_REQUEST['collection']) 493 | ->find() 494 | ->limit($limit) 495 | ->skip($skip) 496 | ->sort(array('_id' => 1)); 497 | } 498 | 499 | $total = $cursor->count(); 500 | $pages = ceil($total / $max); 501 | 502 | if ($pages && $page > $pages) { 503 | header('location: ' . $_SERVER['HTTP_REFERER']); 504 | exit; 505 | } 506 | ?> 507 | 508 |

509 | Databases >> 510 | >> 511 | (count() ?> Documents) 512 |

513 | 514 | 1): ?> 515 |
516 | pages. Go to page 517 | 518 | 519 |
520 | 521 | 522 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 |
ID
545 | $searchQuery) { 552 | if ($fieldName != '_id' && $fieldName[0] != '$' && isset($document[$fieldName])) { 553 | $fieldValue = $document[$fieldName]; 554 | 555 | if (!is_array($fieldValue) && !is_object($fieldValue)) { 556 | $displayValues[] = $fieldName . ': ' . substr(str_replace("\n", '', htmlspecialchars($fieldValue)), 0, 100); 557 | } 558 | } 559 | } 560 | 561 | echo implode(' - ', $displayValues); 562 | } 563 | 564 | if (!isset($displayValues) || !count($displayValues)) { 565 | foreach ($document as $fieldName => $fieldValue) { 566 | if ($fieldName != '_id' && !is_array($fieldValue) && !is_object($fieldValue)) { 567 | echo $fieldName . ': ' . substr(str_replace("\n", '', htmlspecialchars($fieldValue)), 0, 100); 568 | break; 569 | } 570 | } 571 | } 572 | ?> 573 | DeleteDelete
583 | 584 | 585 |
586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | $v): ?> 595 | 596 | 597 | 598 |

Create New Document

599 | 600 | 601 |
602 | 603 | 604 | 605 | 606 | 607 |

608 | Databases >> 609 | >> 610 | >> 611 | 612 |

613 | 614 | 615 |
616 | 617 | 618 | 619 | 620 |
621 | 622 | 623 | $v): ?> 624 | 625 | 626 | 627 |

Edit Document

628 | 629 | 630 |
631 | 632 |
633 | 634 | Delete 635 | 636 | Delete 637 | 638 | 639 | 640 | 641 | 642 | 643 |
644 | 645 | 646 | --------------------------------------------------------------------------------