스프링노트 연동 모듈 추가

git-svn-id: http://xe-core.googlecode.com/svn/sandbox@3114 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
zero 2007-11-30 03:44:14 +00:00
parent 206ffeefa0
commit b05bafd715
50 changed files with 5347 additions and 0 deletions

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<module version="0.1" category="service">
<title xml:lang="ko">스프링노트 연동</title>
<author email_address="zero@zeroboard.com" link="http://www.zeroboard.com" date="2007.11.30">
<name xml:lang="ko">zero</name>
<description xml:lang="ko">스프링노트의 페이지를 제로보드XE에서 연동하여 출력하는 기능을 가지고 있는 모듈입니다.</description>
</author>
</module>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<module>
<grants>
<grant name="list" default="guest">
<title xml:lang="ko">목록</title>
<title xml:lang="zh-CN">目录</title>
<title xml:lang="jp">リスト</title>
<title xml:lang="en">list</title>
</grant>
<grant name="view" default="guest">
<title xml:lang="ko">열람</title>
<title xml:lang="zh-CN">查看</title>
<title xml:lang="jp">閲覧</title>
<title xml:lang="en">view</title>
</grant>
</grants>
<actions>
<action name="dispSpringnoteContent" type="view" index="true" />
<action name="dispSpringnoteAdminContent" type="view" standalone="true" admin_index="true" />
<action name="dispSpringnoteAdminSpringnoteInfo" type="view" standalone="true" />
<action name="dispSpringnoteAdminInsertSpringnote" type="view" standalone="true" />
<action name="dispSpringnoteAdminDeleteSpringnote" type="view" standalone="true" />
<action name="dispSpringnoteAdminGrantInfo" type="view" standalone="true" />
<action name="dispSpringnoteAdminSkinInfo" type="view" standalone="true" />
<action name="procSpringnoteAdminInsertSpringnote" type="controller" standalone="true" />
<action name="procSpringnoteAdminDeleteSpringnote" type="controller" standalone="true" />
<action name="procSpringnoteAdminInsertGrant" type="controller" standalone="true" />
<action name="procSpringnoteAdminUpdateSkinInfo" type="controller" standalone="true" />
</actions>
</module>

View file

@ -0,0 +1,24 @@
<?php
/**
* @file ko.lang.php
* @author zero (zero@nzeo.com)
* @brief 스프링노트(springnote) 모듈의 기본 언어팩
**/
$lang->springnote = "스프링노트";
$lang->springnote_openid = "오픈아이디";
$lang->springnote_userkey = "사용자 Key";
$lang->springnote_pageid = "페이지 번호";
$lang->page_url = "원본 URL";
$lang->page_modified = "최종 수정";
$lang->page_modifier = "최종 수정자";
$lang->cmd_springnote_list = '스프링노트 목록';
$lang->cmd_view_info = '스프링노트 정보';
$lang->about_springnote = "스프링노트는 오픈마루에서 제공하는 위키서비스입니다.<br />스프링노트 제로보드XE모듈은 스프링노트의 특정 페이지들을 내부문서처럼 열람할 수 있는 모듈입니다.";
$lang->about_springnote_openid = "스프링노트에서 페이지를 제작한 오픈아이디를 입력해주세요";
$lang->about_springnote_userkey = '스프링노트 연동을 위한 사용자 Key값을 입력해주셔야 합니다.<br />[<a href="https://api.openmaru.com/delegate_key/springnote?app_id=www.zeroboard.com&openid=" onclick="window.open(this.href);return false;">사용자 키 받기</a>] 를 클릭하셔서 오픈아이디를 입력하시고 생성되는 키값을 입력해주세요.';
$lang->about_springnote_pageid = '사용하시려는 스프링노트 중 특정 페이지를 먼저 출력하고자 하실때 pageid값을 입력해주세요';
?>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,106 @@
<?php
/**
* Listener for HTTP_Request and HTTP_Response objects
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2002-2007, Richard Heyes
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* o The names of the authors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category HTTP
* @package HTTP_Request
* @author Alexey Borzov <avb@php.net>
* @copyright 2002-2007 Richard Heyes
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: Listener.php,v 1.3 2007/05/18 10:33:31 avb Exp $
* @link http://pear.php.net/package/HTTP_Request/
*/
/**
* Listener for HTTP_Request and HTTP_Response objects
*
* This class implements the Observer part of a Subject-Observer
* design pattern.
*
* @category HTTP
* @package HTTP_Request
* @author Alexey Borzov <avb@php.net>
* @version Release: 1.4.1
*/
class HTTP_Request_Listener
{
/**
* A listener's identifier
* @var string
*/
var $_id;
/**
* Constructor, sets the object's identifier
*
* @access public
*/
function HTTP_Request_Listener()
{
$this->_id = md5(uniqid('http_request_', 1));
}
/**
* Returns the listener's identifier
*
* @access public
* @return string
*/
function getId()
{
return $this->_id;
}
/**
* This method is called when Listener is notified of an event
*
* @access public
* @param object an object the listener is attached to
* @param string Event name
* @param mixed Additional data
* @abstract
*/
function update(&$subject, $event, $data = null)
{
echo "Notified of event: '$event'\n";
if (null !== $data) {
echo "Additional data: ";
var_dump($data);
}
}
}
?>

View file

@ -0,0 +1,528 @@
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stig Bakken <ssb@php.net> |
// | Chuck Hagenbuch <chuck@horde.org> |
// +----------------------------------------------------------------------+
//
// $Id: Socket.php,v 1.24 2005/02/03 20:40:16 chagenbu Exp $
require_once 'PEAR.php';
define('NET_SOCKET_READ', 1);
define('NET_SOCKET_WRITE', 2);
define('NET_SOCKET_ERROR', 3);
/**
* Generalized Socket class.
*
* @version 1.1
* @author Stig Bakken <ssb@php.net>
* @author Chuck Hagenbuch <chuck@horde.org>
*/
class Net_Socket extends PEAR {
/**
* Socket file pointer.
* @var resource $fp
*/
var $fp = null;
/**
* Whether the socket is blocking. Defaults to true.
* @var boolean $blocking
*/
var $blocking = true;
/**
* Whether the socket is persistent. Defaults to false.
* @var boolean $persistent
*/
var $persistent = false;
/**
* The IP address to connect to.
* @var string $addr
*/
var $addr = '';
/**
* The port number to connect to.
* @var integer $port
*/
var $port = 0;
/**
* Number of seconds to wait on socket connections before assuming
* there's no more data. Defaults to no timeout.
* @var integer $timeout
*/
var $timeout = false;
/**
* Number of bytes to read at a time in readLine() and
* readAll(). Defaults to 2048.
* @var integer $lineLength
*/
var $lineLength = 2048;
/**
* Connect to the specified port. If called when the socket is
* already connected, it disconnects and connects again.
*
* @param string $addr IP address or host name.
* @param integer $port TCP port number.
* @param boolean $persistent (optional) Whether the connection is
* persistent (kept open between requests
* by the web server).
* @param integer $timeout (optional) How long to wait for data.
* @param array $options See options for stream_context_create.
*
* @access public
*
* @return boolean | PEAR_Error True on success or a PEAR_Error on failure.
*/
function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null)
{
if (is_resource($this->fp)) {
@fclose($this->fp);
$this->fp = null;
}
if (!$addr) {
return $this->raiseError('$addr cannot be empty');
} elseif (strspn($addr, '.0123456789') == strlen($addr) ||
strstr($addr, '/') !== false) {
$this->addr = $addr;
} else {
$this->addr = @gethostbyname($addr);
}
$this->port = $port % 65536;
if ($persistent !== null) {
$this->persistent = $persistent;
}
if ($timeout !== null) {
$this->timeout = $timeout;
}
$openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen';
$errno = 0;
$errstr = '';
if ($options && function_exists('stream_context_create')) {
if ($this->timeout) {
$timeout = $this->timeout;
} else {
$timeout = 0;
}
$context = stream_context_create($options);
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context);
} else {
if ($this->timeout) {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout);
} else {
$fp = @$openfunc($this->addr, $this->port, $errno, $errstr);
}
}
if (!$fp) {
return $this->raiseError($errstr, $errno);
}
$this->fp = $fp;
return $this->setBlocking($this->blocking);
}
/**
* Disconnects from the peer, closes the socket.
*
* @access public
* @return mixed true on success or an error object otherwise
*/
function disconnect()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
@fclose($this->fp);
$this->fp = null;
return true;
}
/**
* Find out if the socket is in blocking mode.
*
* @access public
* @return boolean The current blocking mode.
*/
function isBlocking()
{
return $this->blocking;
}
/**
* Sets whether the socket connection should be blocking or
* not. A read call to a non-blocking socket will return immediately
* if there is no data available, whereas it will block until there
* is data for blocking sockets.
*
* @param boolean $mode True for blocking sockets, false for nonblocking.
* @access public
* @return mixed true on success or an error object otherwise
*/
function setBlocking($mode)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$this->blocking = $mode;
socket_set_blocking($this->fp, $this->blocking);
return true;
}
/**
* Sets the timeout value on socket descriptor,
* expressed in the sum of seconds and microseconds
*
* @param integer $seconds Seconds.
* @param integer $microseconds Microseconds.
* @access public
* @return mixed true on success or an error object otherwise
*/
function setTimeout($seconds, $microseconds)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return socket_set_timeout($this->fp, $seconds, $microseconds);
}
/**
* Returns information about an existing socket resource.
* Currently returns four entries in the result array:
*
* <p>
* timed_out (bool) - The socket timed out waiting for data<br>
* blocked (bool) - The socket was blocked<br>
* eof (bool) - Indicates EOF event<br>
* unread_bytes (int) - Number of bytes left in the socket buffer<br>
* </p>
*
* @access public
* @return mixed Array containing information about existing socket resource or an error object otherwise
*/
function getStatus()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return socket_get_status($this->fp);
}
/**
* Get a specified line of data
*
* @access public
* @return $size bytes of data from the socket, or a PEAR_Error if
* not connected.
*/
function gets($size)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return @fgets($this->fp, $size);
}
/**
* Read a specified amount of data. This is guaranteed to return,
* and has the added benefit of getting everything in one fread()
* chunk; if you know the size of the data you're getting
* beforehand, this is definitely the way to go.
*
* @param integer $size The number of bytes to read from the socket.
* @access public
* @return $size bytes of data from the socket, or a PEAR_Error if
* not connected.
*/
function read($size)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return @fread($this->fp, $size);
}
/**
* Write a specified amount of data.
*
* @param string $data Data to write.
* @param integer $blocksize Amount of data to write at once.
* NULL means all at once.
*
* @access public
* @return mixed true on success or an error object otherwise
*/
function write($data, $blocksize = null)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
if (is_null($blocksize) && !OS_WINDOWS) {
return fwrite($this->fp, $data);
} else {
if (is_null($blocksize)) {
$blocksize = 1024;
}
$pos = 0;
$size = strlen($data);
while ($pos < $size) {
$written = @fwrite($this->fp, substr($data, $pos, $blocksize));
if ($written === false) {
return false;
}
$pos += $written;
}
return $pos;
}
}
/**
* Write a line of data to the socket, followed by a trailing "\r\n".
*
* @access public
* @return mixed fputs result, or an error
*/
function writeLine($data)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return fwrite($this->fp, $data . "\r\n");
}
/**
* Tests for end-of-file on a socket descriptor.
*
* @access public
* @return bool
*/
function eof()
{
return (is_resource($this->fp) && feof($this->fp));
}
/**
* Reads a byte of data
*
* @access public
* @return 1 byte of data from the socket, or a PEAR_Error if
* not connected.
*/
function readByte()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
return ord(@fread($this->fp, 1));
}
/**
* Reads a word of data
*
* @access public
* @return 1 word of data from the socket, or a PEAR_Error if
* not connected.
*/
function readWord()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$buf = @fread($this->fp, 2);
return (ord($buf[0]) + (ord($buf[1]) << 8));
}
/**
* Reads an int of data
*
* @access public
* @return integer 1 int of data from the socket, or a PEAR_Error if
* not connected.
*/
function readInt()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$buf = @fread($this->fp, 4);
return (ord($buf[0]) + (ord($buf[1]) << 8) +
(ord($buf[2]) << 16) + (ord($buf[3]) << 24));
}
/**
* Reads a zero-terminated string of data
*
* @access public
* @return string, or a PEAR_Error if
* not connected.
*/
function readString()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$string = '';
while (($char = @fread($this->fp, 1)) != "\x00") {
$string .= $char;
}
return $string;
}
/**
* Reads an IP Address and returns it in a dot formated string
*
* @access public
* @return Dot formated string, or a PEAR_Error if
* not connected.
*/
function readIPAddress()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$buf = @fread($this->fp, 4);
return sprintf("%s.%s.%s.%s", ord($buf[0]), ord($buf[1]),
ord($buf[2]), ord($buf[3]));
}
/**
* Read until either the end of the socket or a newline, whichever
* comes first. Strips the trailing newline from the returned data.
*
* @access public
* @return All available data up to a newline, without that
* newline, or until the end of the socket, or a PEAR_Error if
* not connected.
*/
function readLine()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$line = '';
$timeout = time() + $this->timeout;
while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) {
$line .= @fgets($this->fp, $this->lineLength);
if (substr($line, -1) == "\n") {
return rtrim($line, "\r\n");
}
}
return $line;
}
/**
* Read until the socket closes, or until there is no more data in
* the inner PHP buffer. If the inner buffer is empty, in blocking
* mode we wait for at least 1 byte of data. Therefore, in
* blocking mode, if there is no data at all to be read, this
* function will never exit (unless the socket is closed on the
* remote end).
*
* @access public
*
* @return string All data until the socket closes, or a PEAR_Error if
* not connected.
*/
function readAll()
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$data = '';
while (!feof($this->fp)) {
$data .= @fread($this->fp, $this->lineLength);
}
return $data;
}
/**
* Runs the equivalent of the select() system call on the socket
* with a timeout specified by tv_sec and tv_usec.
*
* @param integer $state Which of read/write/error to check for.
* @param integer $tv_sec Number of seconds for timeout.
* @param integer $tv_usec Number of microseconds for timeout.
*
* @access public
* @return False if select fails, integer describing which of read/write/error
* are ready, or PEAR_Error if not connected.
*/
function select($state, $tv_sec, $tv_usec = 0)
{
if (!is_resource($this->fp)) {
return $this->raiseError('not connected');
}
$read = null;
$write = null;
$except = null;
if ($state & NET_SOCKET_READ) {
$read[] = $this->fp;
}
if ($state & NET_SOCKET_WRITE) {
$write[] = $this->fp;
}
if ($state & NET_SOCKET_ERROR) {
$except[] = $this->fp;
}
if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) {
return false;
}
$result = 0;
if (count($read)) {
$result |= NET_SOCKET_READ;
}
if (count($write)) {
$result |= NET_SOCKET_WRITE;
}
if (count($except)) {
$result |= NET_SOCKET_ERROR;
}
return $result;
}
}

View file

@ -0,0 +1,410 @@
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002-2004, Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard at php net> |
// +-----------------------------------------------------------------------+
//
// $Id: URL.php,v 1.36 2004/06/19 18:58:50 richard Exp $
//
// Net_URL Class
class Net_URL
{
/**
* Full url
* @var string
*/
var $url;
/**
* Protocol
* @var string
*/
var $protocol;
/**
* Username
* @var string
*/
var $username;
/**
* Password
* @var string
*/
var $password;
/**
* Host
* @var string
*/
var $host;
/**
* Port
* @var integer
*/
var $port;
/**
* Path
* @var string
*/
var $path;
/**
* Query string
* @var array
*/
var $querystring;
/**
* Anchor
* @var string
*/
var $anchor;
/**
* Whether to use []
* @var bool
*/
var $useBrackets;
/**
* PHP4 Constructor
*
* @see __construct()
*/
function Net_URL($url = null, $useBrackets = true)
{
$this->__construct($url, $useBrackets);
}
/**
* PHP5 Constructor
*
* Parses the given url and stores the various parts
* Defaults are used in certain cases
*
* @param string $url Optional URL
* @param bool $useBrackets Whether to use square brackets when
* multiple querystrings with the same name
* exist
*/
function __construct($url = null, $useBrackets = true)
{
$HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
$this->useBrackets = $useBrackets;
$this->url = $url;
$this->user = '';
$this->pass = '';
$this->host = '';
$this->port = 80;
$this->path = '';
$this->querystring = array();
$this->anchor = '';
// Only use defaults if not an absolute URL given
if (!preg_match('/^[a-z0-9]+:\/\//i', $url)) {
$this->protocol = (@$HTTP_SERVER_VARS['HTTPS'] == 'on' ? 'https' : 'http');
/**
* Figure out host/port
*/
if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) AND preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) {
$host = $matches[1];
if (!empty($matches[3])) {
$port = $matches[3];
} else {
$port = $this->getStandardPort($this->protocol);
}
}
$this->user = '';
$this->pass = '';
$this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost');
$this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol));
$this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/';
$this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null;
$this->anchor = '';
}
// Parse the url and store the various parts
if (!empty($url)) {
$urlinfo = parse_url($url);
// Default querystring
$this->querystring = array();
foreach ($urlinfo as $key => $value) {
switch ($key) {
case 'scheme':
$this->protocol = $value;
$this->port = $this->getStandardPort($value);
break;
case 'user':
case 'pass':
case 'host':
case 'port':
$this->$key = $value;
break;
case 'path':
if ($value{0} == '/') {
$this->path = $value;
} else {
$path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path);
$this->path = sprintf('%s/%s', $path, $value);
}
break;
case 'query':
$this->querystring = $this->_parseRawQueryString($value);
break;
case 'fragment':
$this->anchor = $value;
break;
}
}
}
}
/**
* Returns full url
*
* @return string Full url
* @access public
*/
function getURL()
{
$querystring = $this->getQueryString();
$this->url = $this->protocol . '://'
. $this->user . (!empty($this->pass) ? ':' : '')
. $this->pass . (!empty($this->user) ? '@' : '')
. $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port)
. $this->path
. (!empty($querystring) ? '?' . $querystring : '')
. (!empty($this->anchor) ? '#' . $this->anchor : '');
return $this->url;
}
/**
* Adds a querystring item
*
* @param string $name Name of item
* @param string $value Value of item
* @param bool $preencoded Whether value is urlencoded or not, default = not
* @access public
*/
function addQueryString($name, $value, $preencoded = false)
{
if ($preencoded) {
$this->querystring[$name] = $value;
} else {
$this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value);
}
}
/**
* Removes a querystring item
*
* @param string $name Name of item
* @access public
*/
function removeQueryString($name)
{
if (isset($this->querystring[$name])) {
unset($this->querystring[$name]);
}
}
/**
* Sets the querystring to literally what you supply
*
* @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc
* @access public
*/
function addRawQueryString($querystring)
{
$this->querystring = $this->_parseRawQueryString($querystring);
}
/**
* Returns flat querystring
*
* @return string Querystring
* @access public
*/
function getQueryString()
{
if (!empty($this->querystring)) {
foreach ($this->querystring as $name => $value) {
if (is_array($value)) {
foreach ($value as $k => $v) {
$querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v);
}
} elseif (!is_null($value)) {
$querystring[] = $name . '=' . $value;
} else {
$querystring[] = $name;
}
}
$querystring = implode(ini_get('arg_separator.output'), $querystring);
} else {
$querystring = '';
}
return $querystring;
}
/**
* Parses raw querystring and returns an array of it
*
* @param string $querystring The querystring to parse
* @return array An array of the querystring data
* @access private
*/
function _parseRawQuerystring($querystring)
{
$parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY);
$return = array();
foreach ($parts as $part) {
if (strpos($part, '=') !== false) {
$value = substr($part, strpos($part, '=') + 1);
$key = substr($part, 0, strpos($part, '='));
} else {
$value = null;
$key = $part;
}
if (substr($key, -2) == '[]') {
$key = substr($key, 0, -2);
if (@!is_array($return[$key])) {
$return[$key] = array();
$return[$key][] = $value;
} else {
$return[$key][] = $value;
}
} elseif (!$this->useBrackets AND !empty($return[$key])) {
$return[$key] = (array)$return[$key];
$return[$key][] = $value;
} else {
$return[$key] = $value;
}
}
return $return;
}
/**
* Resolves //, ../ and ./ from a path and returns
* the result. Eg:
*
* /foo/bar/../boo.php => /foo/boo.php
* /foo/bar/../../boo.php => /boo.php
* /foo/bar/.././/boo.php => /foo/boo.php
*
* This method can also be called statically.
*
* @param string $url URL path to resolve
* @return string The result
*/
function resolvePath($path)
{
$path = explode('/', str_replace('//', '/', $path));
for ($i=0; $i<count($path); $i++) {
if ($path[$i] == '.') {
unset($path[$i]);
$path = array_values($path);
$i--;
} elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) {
unset($path[$i]);
unset($path[$i-1]);
$path = array_values($path);
$i -= 2;
} elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') {
unset($path[$i]);
$path = array_values($path);
$i--;
} else {
continue;
}
}
return implode('/', $path);
}
/**
* Returns the standard port number for a protocol
*
* @param string $scheme The protocol to lookup
* @return integer Port number or NULL if no scheme matches
*
* @author Philippe Jausions <Philippe.Jausions@11abacus.com>
*/
function getStandardPort($scheme)
{
switch (strtolower($scheme)) {
case 'http': return 80;
case 'https': return 443;
case 'ftp': return 21;
case 'imap': return 143;
case 'imaps': return 993;
case 'pop3': return 110;
case 'pop3s': return 995;
default: return null;
}
}
/**
* Forces the URL to a particular protocol
*
* @param string $protocol Protocol to force the URL to
* @param integer $port Optional port (standard port is used by default)
*/
function setProtocol($protocol, $port = null)
{
$this->protocol = $protocol;
$this->port = is_null($port) ? $this->getStandardPort() : $port;
}
}
?>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
<query id="getSpringnoteList" action="select">
<tables>
<table name="modules" />
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="equal" column="module" default="springnote" />
<condition operation="equal" column="module_category_srl" var="s_module_category_srl" pipe="or" />
</conditions>
<navigation>
<index var="sort_index" default="module_srl" order="desc" />
<list_count var="list_count" default="20" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
</query>

View file

@ -0,0 +1,39 @@
@charset "utf-8";
/* board Title */
.boardHeader { border:1px solid #e1e1dd; border-bottom:none; background:#ffffff url(../images/common/bgH3.gif) repeat-x left bottom; overflow:hidden; _width:100%;}
.boardHeader h3 { float:left; font-size:1.2em; padding:1em 2em .7em 1.2em; background:#ffffff url(../images/common/lineH3.gif) no-repeat right bottom;}
/* board Information */
.boardInformation { width:100%; clear:both; margin:1em 0 .5em 0; overflow:hidden; color:#666666;}
.articleNum { float:left; padding:0 0 0 15px; }
/* account Navigation */
.accountNavigation { float:right; }
.accountNavigation li { float:left; margin-left:7px; list-style:none; padding-top:3px;}
.accountNavigation li a { font-size:12px; white-space:nowrap; color:#666666; text-decoration:none;}
.accountNavigation li.setup a { background:url(../images/common/iconSetup.gif) no-repeat left top; padding-left:14px; }
.accountNavigation li.admin a { background:url(../images/common/iconAdmin.gif) no-repeat left top; padding-left:12px; }
.accountNavigation li.loginAndLogout { background:url(../images/common/line_1x10_e0e0e0.gif) no-repeat left 5px; padding-left:8px; _padding-top:5px;}
*:first-child+html li.loginAndLogout { padding-top:5px; }
.pageSearch { text-align:right; margin-bottom:10px; }
.pageList { border:1px solid #E3E3E2; }
.pageList .page { border-top:1px dotted #EFEFEF; padding:10px; }
.pageList .selected { background-color:#EFEFEF; }
.pageList .noline { border-top:none; }
.pageList .page .title { background:url("../images/common/document.gif") no-repeat left top; padding-left:18px; }
.pageList .page a { text-decoration:none; color:#666666; }
.pageList .page a:hover { text-decoration:underline; color:#333333; }
.pageList .page a:visited { text-decoration:none; color:#999999; }
.pageList .selected a { color:#555555; font-weight:bold; }
.pageList .selected a:visited { color:#555555; font-weight:bold; }
.pageList .page .desc { padding-left:18px; color:#AAAAAA; margin-top:5px;}
.pageInfo table { width:100%; border-left:1px solid #E3E3E2; border-top:1px solid #E3E3E2; margin-bottom:10px; table-layout:fixed;}
.pageInfo table th { overflow:hidden; background-color:#FAF8F4; padding:5px; font-weight:normal; text-align:left; padding-left:10px; color:#606060; border-right:1px solid #E3E3E2; border-bottom:1px solid #E3E3E2; }
.pageInfo table td { overflow:hidden; background-color:#FFFFFF; padding:5px; font-weight:normal; text-align:left; padding-left:10px; color:#5A5A5A; border-right:1px solid #E3E3E2; border-bottom:1px solid #E3E3E2;}
.pageInfo td a { text-decoration:none; color:#888888; }
.pageInfo td a:hover { text-decoration:underline; }
{ border:1px solid #CCCCCC; margin-bottom:10px; }
.pageView { border:1px solid #E3E3E2; padding:20px; margin-bottom:10px; }

View file

@ -0,0 +1,13 @@
@charset "utf-8";
/* board Title */
.boardHeader h3 { border-bottom:3px solid #2895c0; }
/* board Information */
.articleNum { float:left; background:url(../images/cyan/iconArticle.gif) no-repeat left top; }
.articleNum strong { font:bold 11px Tahoma; color:#2895c0;}
/* account Navigation */
.accountNavigation li.join a { background:url(../images/cyan/iconMyInfo.gif) no-repeat left top; padding-left:14px; }
.accountNavigation li.myInfo a { background:url(../images/cyan/iconMyInfo.gif) no-repeat left top; padding-left:14px; }

View file

@ -0,0 +1,13 @@
@charset "utf-8";
/* board Title */
.boardHeader h3 { border-bottom:3px solid #38b549; }
/* board Information */
.articleNum { float:left; background:url(../images/green/iconArticle.gif) no-repeat left top; }
.articleNum strong { font:bold 11px Tahoma; color:#ff6600;}
/* account Navigation */
.accountNavigation li.join a { background:url(../images/green/iconMyInfo.gif) no-repeat left top; padding-left:14px; }
.accountNavigation li.myInfo a { background:url(../images/green/iconMyInfo.gif) no-repeat left top; padding-left:14px; }

View file

@ -0,0 +1,13 @@
@charset "utf-8";
/* board Title */
.boardHeader h3 { border-bottom:3px solid #ac19a9; }
/* board Information */
.articleNum { float:left; background:url(../images/purple/iconArticle.gif) no-repeat left top; }
.articleNum strong { font:bold 11px Tahoma; color:#b1ae00;}
/* account Navigation */
.accountNavigation li.join a { background:url(../images/purple/iconMyInfo.gif) no-repeat left top; padding-left:14px; }
.accountNavigation li.myInfo a { background:url(../images/purple/iconMyInfo.gif) no-repeat left top; padding-left:14px; }

View file

@ -0,0 +1,13 @@
@charset "utf-8";
/* board Title */
.boardHeader h3 { border-bottom:3px solid #ed135a; }
/* board Information */
.articleNum { float:left; background:url(../images/red/iconArticle.gif) no-repeat left top; }
.articleNum strong { font:bold 11px Tahoma; color:#ff6600;}
/* account Navigation */
.accountNavigation li.join a { background:url(../images/red/iconMyInfo.gif) no-repeat left top; padding-left:14px; }
.accountNavigation li.myInfo a { background:url(../images/red/iconMyInfo.gif) no-repeat left top; padding-left:14px; }

View file

@ -0,0 +1,13 @@
@charset "utf-8";
/* board Title */
.boardHeader h3 { border-bottom:3px solid #fe3614; }
/* board Information */
.articleNum { float:left; background:url(../images/white/iconArticle.gif) no-repeat left top; }
.articleNum strong { font:bold 11px Tahoma; color:#ff6600;}
/* account Navigation */
.accountNavigation li.join a { background:url(../images/white/iconMyInfo.gif) no-repeat left top; padding-left:14px; }
.accountNavigation li.myInfo a { background:url(../images/white/iconMyInfo.gif) no-repeat left top; padding-left:14px; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

View file

@ -0,0 +1,120 @@
<!-- JS 파일 로드 -->
<!--%import("js/board.js")-->
<!-- 컬러셋 체크 -->
<!--@if(!$module_info->colorset)-->
{@$module_info->colorset = "white"}
<!--@end-->
<!-- CSS 파일 로드 (컬러셋에 따라서) -->
<!--%import("css/common.css")-->
<!--@if($module_info->colorset == "cyan")--> <!--%import("css/cyan.css")-->
<!--@elseif($module_info->colorset == "red")--> <!--%import("css/red.css")-->
<!--@elseif($module_info->colorset == "green")--> <!--%import("css/green.css")-->
<!--@elseif($module_info->colorset == "purple")--> <!--%import("css/purple.css")-->
<!--@else--> <!--%import("css/white.css")-->
<!--@end-->
<!-- 상단 텍스트 출력 -->
{$module_info->header_text}
<!-- 스킨의 제목/간단한 설명 출력 -->
<!--@if($module_info->title)-->
<div class="boardHeader">
<h3>{$module_info->title}</h3>
</div>
<!--@end-->
<!-- 게시판 정보 -->
<div class="boardInformation">
<!-- 게시물 수 -->
<div class="articleNum">{$lang->document_count} <strong>{number_format(count($pages))}</strong></div>
<!-- 로그인 정보 -->
<ul class="accountNavigation">
<!-- 로그인 되어 있을 경우 -->
<!--@if($is_logged)-->
<!-- 관리자이면 설정 버튼 출력 -->
<!--@if($grant->is_admin)-->
<li class="setup"><a href="{getUrl('act','dispSpringnoteAdminSpringnoteInfo')}">{$lang->cmd_setup}</a></li>
<!--@end-->
<!-- 최고관리자이면 관리자 페이지 버튼 출력 -->
<!--@if($logged_info->is_admin == 'Y')-->
<li class="admin"><a href="{getUrl('','module','admin','act','dispSpringnoteAdminContent')}" onclick="window.open(this.href); return false;">{$lang->cmd_management}</a></li>
<!--@end-->
<!-- 레이아웃이 없으면 회원정보 버튼 출력 -->
<!--@if(!$module_info->layout_srl)-->
<li class="myInfo"><a href="{getUrl('act','dispMemberInfo')}">{$lang->cmd_view_member_info}</a></li>
<li class="loginAndLogout"><a href="{getUrl('act','dispMemberLogout')}">{$lang->cmd_logout}</a></li>
<!--@end-->
<!-- 로그인 되어 있지 않고 레이아웃이 없으면 -->
<!--@elseif(!$is_logged && !$module_info->layout_srl)-->
<li class="join"><a href="{getUrl('act','dispMemberSignUpForm')}">{$lang->cmd_signup}</a></li>
<li class="loginAndLogout"><a href="{getUrl('act','dispMemberLoginForm')}">{$lang->cmd_login}</a></li>
<!--@end-->
<li class="skin_info"><a href="{getUrl('','module','module','act','dispModuleSkinInfo','selected_module',$module_info->module, 'skin', $module_info->skin)}" onclick="popopen(this.href,'skinInfo'); return false;"><img src="./images/common/buttonHelp.gif" alt="Skin Info" width="13" height="13"/></a></li>
</ul>
</div>
<!--@if($page)-->
<!-- 선택된 페이지가 있을 경우 -->
<div class="pageInfo">
<table cellspacing="0">
<col width="160" />
<col />
<tr>
<th>{$lang->title}</th>
<td>{$page->title}</td>
</tr>
<tr>
<th>{$lang->page_url}</th>
<td><a href="{$page->uri}" onclick="window.open(this.href); return false;">{$page->uri}</a></td>
</tr>
<!--@if($page->date_modified)-->
<tr>
<th>{$lang->page_modified}</th>
<td>{$page->date_modified}</td>
</tr>
<tr>
<th>{$lang->page_modifier}</th>
<td><a href="{$page->contributor_modified}" onclick="window.open(this.href);return false;">{$page->contributor_modified}</a></td>
</tr>
<!--@end-->
</table>
</div>
<div class="pageView">
<div class="xhtmlEditorBody background_no">
{$page->source}
</div>
</div>
<!--@end-->
<!-- 전체 목록 -->
<div class="pageSearch">
<form action="./" method="get">
<input type="hidden" name="mid" value="{$mid}" />
<input type="text" name="q" value="{htmlspecialchars($q)}" class="inputTypeText w200" /><span class="button"><input type="submit" value="{$lang->cmd_search}" /></span><span class="button"><input type="button" value="{$lang->cmd_cancel}" onclick="location.href='{getUrl('','mid',$mid)}';return false;" /></span>
</form>
</div>
<div class="pageList">
{@ $_idx = 0 }
<!--@foreach($pages as $key => $val)-->
<div class="page <!--@if(!$_idx)-->noline<!--@end--> <!--@if($val->pageid == $pageid)-->selected<!--@end-->" style="padding-left:{($val->depth+1)*20}px;">
<div class="title"><a href="{getUrl('pageid',$key)}">{$val->title}</a></div>
<!--@if($val->source)--><div class="desc">{$val->source}</div><!--@end-->
</div>
{@ $_idx++}
<!--@end-->
</div>
<!-- 하단 텍스트 출력 -->
{$module_info->footer_text}

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<skin>
<title xml:lang="ko">스프링 노트 연동 기본 스킨</title>
<maker email_address="zero@zeroboard.com" link="http://www.zeroboard.com" date="2007.11.30">
<name xml:lang="ko">zero</name>
<description xml:lang="ko">스프링 노트 연동 모듈의 기본 스킨</description>
</maker>
<colorset>
<color name="white" src="screenshot/white.gif">
<title xml:lang="ko">하얀색(기본)</title>
<title xml:lang="jp">白(デフォルト)</title>
<title xml:lang="zh-CN">白色(基本)</title>
<title xml:lang="en">White (default)</title>
</color>
<color name="cyan" src="screenshot/cyan.gif">
<title xml:lang="ko">청록색</title>
<title xml:lang="jp">青緑</title>
<title xml:lang="zh-CN">青绿色</title>
<title xml:lang="en">Cyan</title>
</color>
<color name="green" src="screenshot/green.gif">
<title xml:lang="ko">초록색</title>
<title xml:lang="jp"></title>
<title xml:lang="zh-CN">绿色</title>
<title xml:lang="en">Green</title>
</color>
<color name="red" src="screenshot/red.gif">
<title xml:lang="ko">빨간색</title>
<title xml:lang="jp"></title>
<title xml:lang="zh-CN">红色</title>
<title xml:lang="en">Red</title>
</color>
<color name="purple" src="screenshot/purple.gif">
<title xml:lang="ko">보라색</title>
<title xml:lang="jp"></title>
<title xml:lang="zh-CN">紫色</title>
<title xml:lang="en">Purple</title>
</color>
</colorset>
<extra_vars>
<var name="title" type="text">
<title xml:lang="ko">게시판 제목</title>
<title xml:lang="jp">掲示板タイトル</title>
<title xml:lang="zh-CN">版面标题</title>
<title xml:lang="en">Title of Board</title>
<description xml:lang="ko">게시판의 제목을 적어주세요.</description>
<description xml:lang="jp">掲示板タイトルを入力してください。</description>
<description xml:lang="zh-CN">请输入版面标题(留空为不显示)。</description>
<description xml:lang="en">Plase input the title of board.</description>
</var>
</extra_vars>
</skin>

View file

@ -0,0 +1,245 @@
<?php
/**
* @class springnoteAdminController
* @author zero (zero@nzeo.com)
* @brief springnote 모듈의 admin controller class
* 관리자 기능을 담당하게 된다.
* 보통 모듈의 관리자 기능은 해당 모듈의 생성이나 정보/권한/스킨정보의 수정등을 담당하게 된다.
**/
class springnoteAdminController extends springnote {
/**
* @brief 초기화
**/
function init() { }
/**
* @brief 방명록 추가
* springnote_name은 mid의 값이 되고 나머지 모듈 공통 값을 받아서 저장을 하게 된다.
**/
function procSpringnoteAdminInsertSpringnote($args = null) {
// 일단 입력된 값들을 모두 받아서 db 입력항목과 그외 것으로 분리
if(!$args) $args = Context::gets('module_srl','module_category_srl','springnote_name','layout_srl','skin','browser_title','description','is_default','header_text','footer_text','admin_id','open_rss');
// springnote모듈임을 명시적으로 지정한다.
$args->module = 'springnote';
// mid값을 직접 받지 않고 springnote_name으로 받는 이유는 mid는 특별히 약속된 변수명이라 오동작이 발생할 수 있어서 다른 이름으로 전달을 받은후 다시 바꾸어준다.
$args->mid = $args->springnote_name;
unset($args->springnote_name);
// is_default일 경우 별다른 요청이 없는 index페이지의 경우 바로 호출이 되는데 이 값을 설정을 하게 된다.
if($args->is_default!='Y') $args->is_default = 'N';
// 기본 값외의 것들을 정리
$extra_var = delObjectVars(Context::getRequestVars(), $args);
unset($extra_var->act);
unset($extra_var->page);
unset($extra_var->springnote_name);
// module_srl이 넘어오면 원 모듈이 있는지 확인
if($args->module_srl) {
$oModuleModel = &getModel('module');
$module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl);
// 만약 원래 모듈이 없으면 새로 입력하기 위한 처리
if($module_info->module_srl != $args->module_srl) unset($args->module_srl);
}
// $extra_var를 serialize
$args->extra_vars = serialize($extra_var);
// module 모듈의 controller 객체 생성
$oModuleController = &getController('module');
// is_default=='Y' 이면
if($args->is_default=='Y') $oModuleController->clearDefaultModule();
/**
* module_srl값이 없다면 신규 등록으로 처리를 한다.
**/
if(!$args->module_srl) {
// module controller를 이용하여 모듈을 생성한다.
$output = $oModuleController->insertModule($args);
$msg_code = 'success_registed';
// 권한의 경우 기본으로 설정을 해주는 것이 좋으며 방명록 모듈의 경우 manager권한을 관리 그룹으로 설정을 한다.
if($output->toBool()) {
// 관리그룹을 member model객체에서 구할 수 있다.
$oMemberModel = &getModel('member');
$admin_group = $oMemberModel->getAdminGroup();
$admin_group_srl = $admin_group->group_srl;
$module_srl = $output->get('module_srl');
$grants = serialize(array('manager'=>array($admin_group_srl)));
// module controller의 module 권한 설정 method를 이용하여 기본 권한을 적용한다.
$oModuleController->updateModuleGrant($module_srl, $grants);
}
/**
* module_srl이 있다면 모듈의 정보를 수정한다
**/
} else {
$output = $oModuleController->updateModule($args);
$msg_code = 'success_updated';
}
// 결과값에 오류가 있을 경우 그대로 객체 리턴.
if(!$output->toBool()) return $output;
// 등록후 페이지 이동을 위해 변수 설정 및 메세지를 설정한다.
$this->add('page',Context::get('page'));
$this->add('module_srl',$output->get('module_srl'));
$this->setMessage($msg_code);
}
/**
* @brief 방명록 삭제
**/
function procSpringnoteAdminDeleteSpringnote() {
// 삭제할 대상 방명록의 module_srl을 구한다.
$module_srl = Context::get('module_srl');
// 원본을 구해온다
$oModuleController = &getController('module');
$output = $oModuleController->deleteModule($module_srl);
// 삭제 처리시 오류가 발생하면 결과 객체를 바로 리턴한다.
if(!$output->toBool()) return $output;
// 등록후 페이지 이동을 위해 변수 설정 및 메세지를 설정한다.
$this->add('module','springnote');
$this->add('page',Context::get('page'));
$this->setMessage('success_deleted');
}
/**
* @brief 권한 설정
* 생성된 방명록에 ./conf/module.xml에 정의된 권한과 관리자가 선택한 그룹의 값을 연동하여 권한을 설정하게 된다.
**/
function procSpringnoteAdminInsertGrant() {
// 대상 방명록(모듈)의 고유값인 module_srl을 체크한다.
$module_srl = Context::get('module_srl');
/**
* 모듈의 권한 목록을 가져옴
* xml_info springnote모듈이 요청되었다고 판단될때 ModuleObject에서 이미 세팅해 놓은 상태이다.
**/
$grant_list = $this->xml_info->grant;
/**
* 권한의 목록을 loop로 돌면서 권한 설정을 한다.
* zbxe의 경우 가능한 간단한 xmlrpc사용을 위해서 배열의 경우 |@| pipe로 하여 하나의 string으로 전달한다.
* 요청받은 권한의 대상 그룹과 권한을 배열로 serialize하여 modules테이블에 module_srl을 키로 rows에 데이터를 적용한다.
**/
if(count($grant_list)) {
foreach($grant_list as $key => $val) {
$group_srls = Context::get($key);
if($group_srls) $arr_grant[$key] = explode('|@|',$group_srls);
}
$grants = serialize($arr_grant);
}
// 권한 설정은 모듈 공통이라 module 모듈의 controller을 생성하여 저장하도록 한다.
$oModuleController = &getController('module');
$oModuleController->updateModuleGrant($module_srl, $grants);
// 권한 설정후 돌아갈 페이지를 위하여 module_srl값을 세팅하고 성공 메세지 역시 세팅한다.
$this->add('module_srl',Context::get('module_srl'));
$this->setMessage('success_registed');
}
/**
* @brief 스킨 정보 업데이트
* 스킨 정보는 skin.xml파일의 extra_vars와 입력된 변수값을 조합하여 serialize하여 modules 테이블에 module_srl을 키로 하여 저장을 하게 된다.
**/
function procSpringnoteAdminUpdateSkinInfo() {
// module_srl에 해당하는 정보들을 가져오기
$module_srl = Context::get('module_srl');
// 어떤 스킨이 사용중인지 확인하기 위해서 module_srl을 이용하여 모듈의 정보를 구하고 스킨을 구한다.
$oModuleModel = &getModel('module');
$module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl);
$skin = $module_info->skin;
// 스킨의 정보르 구해옴 (extra_vars를 체크하기 위해서)
$skin_info = $oModuleModel->loadSkinInfo($this->module_path, $skin);
// 입력받은 변수들을 체크 (mo, act, module_srl, page등 기본적인 변수들 없앰)
$obj = Context::getRequestVars();
unset($obj->act);
unset($obj->module_srl);
unset($obj->page);
// 원 skin_info에서 extra_vars의 type이 image일 경우 별도 처리를 해줌
if($skin_info->extra_vars) {
foreach($skin_info->extra_vars as $vars) {
if($vars->type!='image') continue;
$image_obj = $obj->{$vars->name};
// 삭제 요청에 대한 변수를 구함
$del_var = $obj->{"del_".$vars->name};
unset($obj->{"del_".$vars->name});
if($del_var == 'Y') {
@unlink($module_info->{$vars->name});
continue;
}
// 업로드 되지 않았다면 이전 데이터를 그대로 사용
if(!$image_obj['tmp_name']) {
$obj->{$vars->name} = $module_info->{$vars->name};
continue;
}
// 정상적으로 업로드된 파일이 아니면 무시
if(!is_uploaded_file($image_obj['tmp_name'])) {
unset($obj->{$vars->name});
continue;
}
// 이미지 파일이 아니어도 무시
if(!eregi("\.(jpg|jpeg|gif|png)$", $image_obj['name'])) {
unset($obj->{$vars->name});
continue;
}
// 경로를 정해서 업로드
$path = sprintf("./files/attach/images/%s/", $module_srl);
// 디렉토리 생성
if(!FileHandler::makeDir($path)) return false;
$filename = $path.$image_obj['name'];
// 파일 이동
if(!move_uploaded_file($image_obj['tmp_name'], $filename)) {
unset($obj->{$vars->name});
continue;
}
// 변수를 바꿈
unset($obj->{$vars->name});
$obj->{$vars->name} = $filename;
}
}
// serialize하여 저장
$skin_vars = serialize($obj);
// module controller객체를 생성하여 module_srl을 키로 한 rows에 serialize한 스킨 정보를 적용한다.
$oModuleController = &getController('module');
$oModuleController->updateModuleSkinVars($module_srl, $skin_vars);
/**
* 스킨 정보는 첨부파일때문에 xml로 전달이 되지 않고 POST로 전송이 되어 왔으므로 템플릿을 이용하여 프레임을 refresh시키도록 한다.
* 스킨 정보를 수정할때 숨어 있는 iframe을 target으로 삼기에 기본 레이아웃을 이용하면 되므로 직접 레이아웃 경로와 파일을 기본으로 지정한다.
**/
$this->setLayoutPath('./common/tpl');
$this->setLayoutFile('default_layout.html');
$this->setTemplatePath($this->module_path.'tpl');
$this->setTemplateFile("top_refresh.html");
}
}
?>

View file

@ -0,0 +1,184 @@
<?php
/**
* @class springnoteAdminView
* @author zero (zero@nzeo.com)
* @brief springnote 모듈의 admin view class
* 방명록 관리자 기능은 생성된 모듈 목록, 신규 등록 수정, 권한의 설정으로 이루어진다.
**/
class springnoteAdminView extends springnote {
/**
* @brief 초기화
* 손쉬운 사용을 위해서 module_srl이 넘어올 경우 해당 방명록의 모듈 정보를 미리 구해서 세팅해 놓도록 한다.
* method에서 하거나 별도의 method를 만들어서 호출하면 되지만 코드의 양을 줄이고 직관성을 높이기 위해서 설정한 코드이다.
**/
function init() {
// module_srl값을 구해온다.
$module_srl = Context::get('module_srl');
// 요청된 module_srl값이 없는데 현재 모듈의 module_srl값이 있다는 것은 방명록의 서비스 부분에서 설정링크를 통해서 바로 설정을 하는 경우이다.
if(!$module_srl && $this->module_srl) {
$module_srl = $this->module_srl;
Context::set('module_srl', $module_srl);
}
// module info를 구하기 위해 module model 객체 생성
$oModuleModel = &getModel('module');
// 모듈 카테고리 목록을 구함
$module_category = $oModuleModel->getModuleCategories();
Context::set('module_category', $module_category);
// module_srl이 있다면 요청된 모듈의 정보를 미리 구해 놓음
if($module_srl) {
$module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl);
if(!$module_info) {
Context::set('module_srl','');
$this->act = 'list';
} else {
$this->module_info = $module_info;
Context::set('module_info',$module_info);
}
}
// 템플릿 경로 지정, 관리자 페이지를 위한 템플릿은 별도의 스킨 기능이 없이 ./modules/모듈/tpl/ 에 위치해 놓기에 바로 지정을 해 놓는다.
$template_path = sprintf("%stpl/",$this->module_path);
$this->setTemplatePath($template_path);
}
/**
* @brief 생성된 방명록들의 목록을 보여줌
* springnote이라는 module명으로 등록된 모듈을 구하기 위해서 몇가지 설정을 후에 쿼리를 수행한다.
* 쿼리수행은 executeQuery(모듈명.쿼리아이디, 인자변수) 하게 되며 쿼리아이디에 해당하는 xml파일은 모듈의 queries디렉토리에 지정이 되어 있다.
*
* 특정 module의 목록은 module model객체에서 구할 있지만 검색등의 모듈마다 다른 조건 때문에 모듈별로 쿼리를 생성해 놓는다.
* 모든 모듈의 결과물(mid) modules 테이블에 저장이 된다.
**/
function dispSpringnoteAdminContent() {
$args->sort_index = "module_srl"; ///< 정렬 순서는 모듈의 sequence값으로 하고 정렬은 역순. 즉 생성된 순으로 한다.
$args->page = Context::get('page'); ///< 현재 페이지를 설정
$args->list_count = 40; ///< 한페이지에 40개씩 보여주기로 고정.
$args->page_count = 10; ///< 페이지의 수는 10개로 제한.
$args->s_module_category_srl = Context::get('module_category_srl'); ///< 모듈분류값을 인자로 추가
$output = executeQuery('springnote.getSpringnoteList', $args); ///< springnote.getGuesbookList 쿼리 실행 (./modules/springnote/query/getSpringnoteList.xml)
/**
* 템플릿에 쓰기 위해서 context::set
* xml query에 navigation이 있고 list_count가 정의되어 있으면 결과 변수에 아래 5가지의 값이 세팅이 된다.
**/
Context::set('total_count', $output->total_count);
Context::set('total_page', $output->total_page);
Context::set('page', $output->page);
Context::set('springnote_list', $output->data);
Context::set('page_navigation', $output->page_navigation);
// 템플릿 파일 지정 (./modules/springnote/tpl/index.html파일이 지정이 됨)
$this->setTemplateFile('index');
}
/**
* @brief 선택된 방명록의 정보 출력
**/
function dispSpringnoteAdminSpringnoteInfo() {
// module_srl 값이 없다면 그냥 index 페이지를 보여줌
if(!Context::get('module_srl')) return $this->dispSpringnoteAdminContent();
// 레이아웃이 정해져 있다면 레이아웃 정보를 추가해줌(layout_title, layout)
if($this->module_info->layout_srl) {
$oLayoutModel = &getModel('layout');
$layout_info = $oLayoutModel->getLayout($this->module_info->layout_srl);
$this->module_info->layout = $layout_info->layout;
$this->module_info->layout_title = $layout_info->layout_title;
}
// 정해진 스킨이 있으면 해당 스킨의 정보를 구함
if($this->module_info->skin) {
$oModuleModel = &getModel('module');
$skin_info = $oModuleModel->loadSkinInfo($this->module_path, $this->module_info->skin);
$this->module_info->skin_title = $skin_info->title;
}
// 템플릿 파일 지정
$this->setTemplateFile('springnote_info');
}
/**
* @brief 방명록 설정 출력
**/
function dispSpringnoteAdminInsertSpringnote() {
// 스킨 목록을 구해옴
$oModuleModel = &getModel('module');
$skin_list = $oModuleModel->getSkins($this->module_path);
Context::set('skin_list',$skin_list);
// 레이아웃 목록을 구해옴
$oLayoutMode = &getModel('layout');
$layout_list = $oLayoutMode->getLayoutList();
Context::set('layout_list', $layout_list);
// 템플릿 파일 지정
$this->setTemplateFile('springnote_insert');
}
/**
* @brief 방명록 삭제 화면 출력
**/
function dispSpringnoteAdminDeleteSpringnote() {
if(!Context::get('module_srl')) return $this->dispSpringnoteAdminContent();
$module_info = Context::get('module_info');
Context::set('module_info',$module_info);
// 템플릿 파일 지정
$this->setTemplateFile('springnote_delete');
}
/**
* @brief 스킨 정보 보여줌
**/
function dispSpringnoteAdminSkinInfo() {
// 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음
$module_info = Context::get('module_info');
$skin = $module_info->skin;
$oModuleModel = &getModel('module');
$skin_info = $oModuleModel->loadSkinInfo($this->module_path, $skin);
// skin_info에 extra_vars 값을 지정
if(count($skin_info->extra_vars)) {
foreach($skin_info->extra_vars as $key => $val) {
$name = $val->name;
$type = $val->type;
$value = $module_info->{$name};
if($type=="checkbox"&&!$value) $value = array();
$skin_info->extra_vars[$key]->value= $value;
}
}
Context::set('skin_info', $skin_info);
$this->setTemplateFile('skin_info');
}
/**
* @brief 권한 목록 출력
**/
function dispSpringnoteAdminGrantInfo() {
// module_srl을 구함
$module_srl = Context::get('module_srl');
// module.xml에서 권한 관련 목록을 구해옴
$grant_list = $this->xml_info->grant;
Context::set('grant_list', $grant_list);
// 권한 그룹의 목록을 가져온다
$oMemberModel = &getModel('member');
$group_list = $oMemberModel->getGroups();
Context::set('group_list', $group_list);
$this->setTemplateFile('grant_list');
}
}
?>

View file

@ -0,0 +1,54 @@
<?php
/**
* @class springnote
* @author zero (zero@nzeo.com)
* @brief springnote 모듈의 high 클래스
**/
class springnote extends ModuleObject {
/**
* @brief 설치시 추가 작업이 필요할시 구현
**/
function moduleInstall() {
// action forward에 등록 (관리자 모드에서 사용하기 위함)
$oModuleController = &getController('module');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteContent');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteAdminContent');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteAdminSpringnoteInfo');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteAdminInsertSpringnote');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteAdminDeleteSpringnote');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteAdminGrantInfo');
$oModuleController->insertActionForward('springnote', 'view', 'dispSpringnoteAdminSkinInfo');
$oModuleController->insertActionForward('springnote', 'controller', 'procSpringnoteAdminInsertSpringnote');
$oModuleController->insertActionForward('springnote', 'controller', 'procSpringnoteAdminDeleteSpringnote');
$oModuleController->insertActionForward('springnote', 'controller', 'procSpringnoteAdminInsertGrant');
return new Object();
}
/**
* @brief 설치가 이상이 없는지 체크하는 method
**/
function checkUpdate() {
$oModuleModel = &getModel('module');
if(!$oModuleModel->getActionForward('dispSpringnoteContent')) return true;
return false;
}
/**
* @brief 업데이트 실행
**/
function moduleUpdate() {
$this->moduleInstall();
return new Object(0,'success_updated');
}
/**
* @brief 캐시 파일 재생성
**/
function recompileCache() {
}
}
?>

View file

@ -0,0 +1,173 @@
<?php
/**
* @class springnoteModel
* @author zero (zero@nzeo.com)
* @brief springnote모듈의 model 클래스
**/
set_include_path("./modules/springnote/lib/PEAR");
require_once('PEAR.php');
require_once('HTTP/Request.php');
class springnoteModel extends springnote {
var $userid = '';
var $userkey = '';
var $appkey = '82dee99105c92c166bb8586415d47283b9a54cd2';
var $server = 'api.springnote.com';
var $port = 80;
/**
* @brief 초기화
**/
function init() {
}
/**
* @brief 스프링노트 페이지를 가져오기 위한 기본 설정
**/
function setInfo($userid, $userkey) {
$this->userid = $userid;
$this->userkey = $userkey;
}
/**
* @brief url 생성
**/
function getUrl($pageid = null) {
return sprintf('http://%s:%s/pages%s.xml', $this->server, $this->port, $pageid?'/'.$pageid:'');
}
/**
* @brief userid 생성
**/
function getUserID() {
return htmlentities($this->userid, ENT_QUOTES, 'UTF-8');
}
/**
* @brief password 생성
**/
function getPassword() {
return $this->userkey.'.'.$this->appkey;
}
/**
* @brief HTTP request 객체 생성
**/
function getRequest($url) {
$oReqeust = new HTTP_Request($url);
$oReqeust->addHeader('Content-Type', 'application/xml');
$oReqeust->setMethod('GET');
$oReqeust->setBasicAuth($this->getUserID(), $this->getPassword());
return $oReqeust;
}
/**
* @brief springnote 페이지 정보 가져오기
**/
function getPage($pageid) {
$url = $this->getUrl($pageid);
$oReqeust = $this->getRequest($url);
$oResponse = $oReqeust->sendRequest();
if (PEAR::isError($oResponse)) return null;
$body = $oReqeust->getResponseBody();
$oXmlParser = new XmlParser();
$xmldoc = $oXmlParser->parse($body);
$page->identifier = $xmldoc->page->identifier->body;
$page->title = $xmldoc->page->title->body;
$page->relation_is_part_of = $xmldoc->page->relation_is_part_of->body;
$page->date_modified = $xmldoc->page->date_modified->body;
$page->uri = $xmldoc->page->uri->body;
$page->date_created = $xmldoc->page->date_created->body;
$page->rights = $xmldoc->page->rights->body;
$page->creator = $xmldoc->page->creator->body;
$page->contributor_modified = $xmldoc->page->contributor_modified->body;
$page->version = $xmldoc->page->version->body;
$page->tags = $xmldoc->page->tags->body;
$page->body = trim($xmldoc->page->body);
$page->source = trim($xmldoc->page->source->body);
$page->source = preg_replace('"\/pages\/([0-9]+)"','./?mid='.Context::get('mid').'&pageid=\\1', $page->source);
$uri = preg_replace('/pages(.*)$/i','',$page->uri);
$page->css_files = array(
sprintf('%sstylesheets/xhtmlContent.css?%d', $uri, time()),
sprintf('%sstylesheets/template.css?%d', $uri, time()),
);
return $page;
}
/**
* @brief springnote 페이지 목록 가져오기
**/
function getPages($query = null, $fulltext = true) {
if($query) $url = sprintf('%s?q=%s&fulltext=%d', $this->getUrl(), urlencode($query), $fulltext?1:0);
else $url = $this->getUrl();
$oReqeust = $this->getRequest($url);
$oResponse = $oReqeust->sendRequest();
if (PEAR::isError($oResponse)) return array();
$body = $oReqeust->getResponseBody();
$oXmlParser = new XmlParser();
$xmldoc = $oXmlParser->parse($body);
// 페이지 목록 정리
$output = array();
$pages = array();
$root = null;
if(count($xmldoc->pages->page)) {
// 일단 서버에서 보내주는 대로 목록을 받음
foreach($xmldoc->pages->page as $val) {
$obj = null;
$obj->pageid = $val->identifier->body;
$obj->title = $val->title->body;
$obj->relation_is_part_of = $val->relation_is_part_of->body;
$obj->date_modified = $val->date_modified->body;
$obj->uri = $val->uri->body;
$obj->source = trim($val->source->body);
if($query && !$obj->source) continue;
$pages[$obj->pageid] = $obj;
}
// parent/chlid관계로 묶음
foreach($pages as $pageid => $page) {
if($page->relation_is_part_of) $pages[$page->relation_is_part_of]->child[] = &$pages[$pageid];
else $root->child[] = &$pages[$pageid];
}
$pages = array();
$this->arrangePages($pages, $root->child, 0);
}
return $pages;
}
/**
* @brief 스프링노트 서버에서 보내준 페이지를 정렬
**/
function arrangePages(&$pages, $list, $depth) {
if(!count($list)) return;
foreach($list as $key => $val) {
$child = $val->child;
unset($val->child);
$val->depth = $depth;
$pages[$val->pageid] = $val;
if($child) $this->arrangePages($pages, $child,$depth+1);
}
}
}
?>

View file

@ -0,0 +1,77 @@
<?php
/**
* @class springnoteView
* @author zero (zero@nzeo.com)
* @brief springnote 모듈의 admin view 클래스
**/
class springnoteView extends springnote {
/**
* @brief 초기화
**/
function init() {
/**
* 템플릿에서 사용할 변수를 Context::set()
* 혹시 사용할 있는 module_srl 변수를 설정한다.
**/
if($this->module_srl) Context::set('module_srl',$this->module_srl);
/**
* 현재 방명록 모듈의 정보를 module_info라는 이름으로 템플릿에서 사용할 있게 하기 위해 세팅한다
**/
Context::set('module_info',$this->module_info);
/**
* 모듈정보에서 넘어오는 skin값을 이용하여 최종 출력할 템플릿의 위치를 출력한다.
* $this->module_path는 ./modules/guestbook/ 값을 가지고 있다
**/
$template_path = sprintf("%sskins/%s/",$this->module_path, $this->module_info->skin);
$this->setTemplatePath($template_path);
}
/**
* @brief 목록 출력 (관리자용)
**/
function dispSpringnoteContent() {
// 권한 체크
if(!$this->grant->list) return $this->dispSpringnoteMessage('msg_not_permitted');
$pageid = (int)Context::get('pageid');
if(!$pageid) $pageid = $this->module_info->pageid;
$q = Context::get('q');
$oSpringnoteModel = &getModel('springnote');
$oSpringnoteModel->setInfo($this->module_info->openid, $this->module_info->userkey);
// 특정 페이지 선택시 페이지 정보 가져오기
if($this->grant->view && $pageid) {
$page = $oSpringnoteModel->getPage($pageid);
for($i=0;$i<count($page->css_files);$i++) {
$css_file = $page->css_files[$i];
Context::addCssFile($css_file);
}
}
// 페이지 목록 가져오기
$pages = $oSpringnoteModel->getPages($q, true);
Context::set('page', $page);
Context::set('pages', $pages);
$this->setTemplateFile('list');
}
/**
* @brief 메세지 출력
**/
function dispSpringnoteMessage($msg_code) {
$msg = Context::getLang($msg_code);
if(!$msg) $msg = $msg_code;
Context::set('message', $msg);
$this->setTemplateFile('message');
}
}
?>

View file

@ -0,0 +1,10 @@
<filter name="delete_springnote" module="springnote" act="procSpringnoteAdminDeleteSpringnote">
<form>
<node target="module_srl" required="true" />
</form>
<response callback_func="completeDeleteSpringnote">
<tag name="error" />
<tag name="message" />
<tag name="page" />
</response>
</filter>

View file

@ -0,0 +1,11 @@
<filter name="insert_grant" module="springnote" act="procSpringnoteAdminInsertGrant" confirm_msg_code="confirm_submit">
<form>
<node target="module_srl" required="true" filter="number" />
</form>
<response callback_func="completeInsertGrant">
<tag name="error" />
<tag name="message" />
<tag name="page" />
<tag name="module_srl" />
</response>
</filter>

View file

@ -0,0 +1,37 @@
<filter name="insert_springnote" module="springnote" act="procSpringnoteAdminInsertSpringnote" confirm_msg_code="confirm_submit">
<form>
<node target="mid" required="true" filter="alpha_number" />
<node target="springnote_openid" required="true" maxlength="250" />
<node target="springnote_userkey" required="true" maxlength="250" />
<node target="browser_title" required="true" maxlength="250" />
</form>
<parameter>
<param name="springnote_name" target="mid" />
<param name="openid" target="springnote_openid" />
<param name="userkey" target="springnote_userkey" />
<param name="pageid" target="springnote_pageid" />
<param name="springnote_name" target="mid" />
<param name="module_srl" target="module_srl" />
<param name="module_category_srl" target="module_category_srl" />
<param name="layout_srl" target="layout_srl" />
<param name="skin" target="skin" />
<param name="browser_title" target="browser_title" />
<param name="use_category" target="use_category" />
<param name="list_count" target="list_count" />
<param name="page_count" target="page_count" />
<param name="is_default" target="is_default" />
<param name="description" target="description" />
<param name="header_text" target="header_text" />
<param name="footer_text" target="footer_text" />
<param name="admin_id" target="admin_id" />
<param name="open_rss" target="open_rss" />
</parameter>
<response callback_func="completeInsertSpringnote">
<tag name="error" />
<tag name="message" />
<tag name="module" />
<tag name="act" />
<tag name="page" />
<tag name="module_srl" />
</response>
</filter>

View file

@ -0,0 +1,38 @@
<!--#include("./header.html")-->
<!--%import("filter/insert_grant.xml")-->
<div class="infoText">{nl2br($lang->about_grant)}</div>
<form action="./" method="post" onsubmit="return procFilter(this, insert_grant)">
<input type="hidden" name="page" value="{$page}" />
<input type="hidden" name="module_srl" value="{$module_srl}" />
<table cellspacing="0" class="adminTable">
<col width="130" />
<col width="*" />
<col width="80" />
<col width="80" />
<caption>{$lang->target}</caption>
<tbody>
<!--@foreach($grant_list as $key => $val)-->
<tr>
<th scope="row">{$val->title}</th>
<td class="left">
<!--@foreach($group_list as $k => $v)-->
<input type="checkbox" class="checkbox" name="{$key}" value="{$v->group_srl}" id="grant_{$key}_{$v->group_srl}" <!--@if(is_array($module_info->grants[$key])&&in_array($v->group_srl,$module_info->grants[$key]))-->checked="checked"<!--@end-->/>
<label for="grant_{$key}_{$v->group_srl}">{$v->title}</label>
<!--@end-->
</td>
<td><a href="#" onclick="doSelectAll(this, '{$key}')" class="blue">{$lang->cmd_select_all}</a></td>
<td><a href="#" onclick="doUnSelectAll(this, '{$key}')" class="red">{$lang->cmd_unselect_all}</a></td>
</tr>
<!--@end-->
<tr>
<th scope="row" colspan="4" class="button">
<span class="button"><input type="submit" value="{$lang->cmd_save}" accesskey="s" /></span>
</th>
</tr>
</tbody>
</table>
</form>

View file

@ -0,0 +1,25 @@
<!--%import("js/springnote_admin.js")-->
<h3>{$lang->springnote} <span class="gray">{$lang->cmd_management}</span></h3>
<div class="infoText">{nl2br($lang->about_springnote)}</div>
<!--@if($module_info)-->
<div class="header4">
<!--@if($module_info->mid)-->
<h4>{$module_info->mid} <!--@if($module_info->is_default=='N')--><span class="bracket">({$lang->is_default})</span><!--@end--> <span class="vr">|</span> <a href="{getUrl('','mid',$module_info->mid)}" onclick="window.open(this.href); return false;" class="view">View</a></h4>
<!--@end-->
<ul class="localNavigation">
<!--@if($module=='admin')-->
<li <!--@if($act=='dispSpringnoteAdminContent')-->class="on"<!--@end-->><a href="{getUrl('act','dispSpringnoteAdminContent','module_srl','')}">{$lang->cmd_springnote_list}</a></li>
<!--@else-->
<li><a href="{getUrl('act','')}">{$lang->cmd_back}</a></li>
<!--@end-->
<li <!--@if($act=='dispSpringnoteAdminSpringnoteInfo')-->class="on"<!--@end-->><a href="{getUrl('act','dispSpringnoteAdminSpringnoteInfo')}">{$lang->cmd_view_info}</a></li>
<li <!--@if($act=='dispSpringnoteAdminGrantInfo')-->class="on"<!--@end-->><a href="{getUrl('act','dispSpringnoteAdminGrantInfo')}">{$lang->cmd_manage_grant}</a></li>
<li <!--@if($act=='dispSpringnoteAdminSkinInfo')-->class="on"<!--@end-->><a href="{getUrl('act','dispSpringnoteAdminSkinInfo')}">{$lang->cmd_manage_skin}</a></li>
</ul>
</div>
<!--@end-->

View file

@ -0,0 +1,79 @@
<!--#include("header.html")-->
<!-- 정보 -->
<div class="tableSummaryType1">
Total <strong>{number_format($total_count)}</strong>, Page <strong>{number_format($page)}</strong>/{number_format($total_page)}
</div>
<!-- 목록 -->
<table cellspacing="0" class="adminTable">
<col width="50" />
<col width="130" />
<col />
<col width="80" />
<col width="50" />
<col width="50" />
<thead>
<tr>
<th scope="col">{$lang->no}</th>
<th scope="col">
<form action="./" method="get" onsubmit="return doChangeCategory(this);">
<input type="hidden" name="module" value="{$module}" />
<input type="hidden" name="act" value="{$act}" />
<select name="module_category_srl" class="w80">
<option value="">{$lang->module_category}</option>
<!--@foreach($module_category as $key => $val)-->
<option value="{$key}" <!--@if($module_category_srl==$key)-->selected="selected"<!--@end-->>{$val->title}</option>
<!--@end-->
<option value="">---------</option>
<option value="-1">{$lang->cmd_management}</option>
</select>
<input type="submit" name="go_button" id="go_button" value="GO" class="buttonTypeGo" />
</form>
</th>
<th scope="col">{$lang->mid} / {$lang->browser_title}</th>
<th scope="col">{$lang->regdate}</th>
<th scope="col">{$lang->cmd_view}</th>
<th scope="col">{$lang->cmd_delete}</th>
</tr>
</thead>
<tbody>
<!--@foreach($springnote_list as $no => $val)-->
<tr>
<td class="tahoma">{$no}</td>
<td>
<!--@if(!$val->module_category_srl)-->
{$lang->not_exists}
<!--@else-->
{$module_category[$val->module_category_srl]->title}
<!--@end-->
</td>
<td class="left subject">
{$val->mid} -
<a href="{getUrl('act','dispSpringnoteAdminSpringnoteInfo','module_srl',$val->module_srl)}" class="blue">{htmlspecialchars($val->browser_title)}</a>
</td>
<td class="tahoma">{zdate($val->regdate,"Y-m-d")}</td>
<td class="blue"><a href="{getUrl('','mid',$val->mid)}" onclick="window.open(this.href); return false;">{$lang->cmd_view}</a></td>
<td class="red"><!--@if($val->is_default!='Y')--><a href="{getUrl('act','dispSpringnoteAdminDeleteSpringnote','module_srl', $val->module_srl)}">{$lang->cmd_delete}</a><!--@end--></td>
</tr>
<!--@end-->
</tbody>
</table>
<!-- 버튼 -->
<div class="fr gap1">
<a href="{getUrl('act','dispSpringnoteAdminInsertSpringnote','module_srl','')}" class="button"><span>{$lang->cmd_make}</span></a>
</div>
<!-- 페이지 네비게이션 -->
<div class="pageNavigation">
<a href="{getUrl('page','','module_srl','')}" class="goToFirst"><img src="../../admin/tpl/images/bottomGotoFirst.gif" alt="{$lang->first_page}" width="7" height="5" /></a>
<!--@while($page_no = $page_navigation->getNextPage())-->
<!--@if($page == $page_no)-->
<span class="current">{$page_no}</span>
<!--@else-->
<a href="{getUrl('page',$page_no,'module_srl','')}">{$page_no}</a>
<!--@end-->
<!--@end-->
<a href="{getUrl('page',$page_navigation->last_page,'module_srl','')}" class="goToLast"><img src="../../admin/tpl/images/bottomGotoLast.gif" alt="{$lang->last_page}" width="7" height="5" /></a>
</div>

View file

@ -0,0 +1,79 @@
/**
* @file modules/springnote/js/springnote_admin.js
* @author zero (zero@nzeo.com)
* @brief springnote 모듈의 관리자용 javascript
**/
/* 모듈 생성 후 */
function completeInsertSpringnote(ret_obj) {
var error = ret_obj['error'];
var message = ret_obj['message'];
var page = ret_obj['page'];
var module_srl = ret_obj['module_srl'];
alert(message);
var url = current_url.setQuery('act','dispSpringnoteAdminSpringnoteInfo');
if(module_srl) url = url.setQuery('module_srl',module_srl);
if(page) url.setQuery('page',page);
location.href = url;
}
/* 모듈 삭제 후 */
function completeDeleteSpringnote(ret_obj) {
var error = ret_obj['error'];
var message = ret_obj['message'];
var page = ret_obj['page'];
alert(message);
var url = current_url.setQuery('act','dispSpringnoteAdminContent').setQuery('module_srl','');
if(page) url = url.setQuery('page',page);
location.href = url;
}
/* 권한 관련 */
function doSelectAll(obj, key) {
var fo_obj = obj.parentNode;
while(fo_obj.nodeName != 'FORM') {
fo_obj = fo_obj.parentNode;
}
for(var i=0;i<fo_obj.length;i++) {
var tobj = fo_obj[i];
if(tobj.name == key) tobj.checked=true;
}
}
function doUnSelectAll(obj, key) {
var fo_obj = obj.parentNode;
while(fo_obj.nodeName != 'FORM') {
fo_obj = fo_obj.parentNode;
}
for(var i=0;i<fo_obj.length;i++) {
var tobj = fo_obj[i];
if(tobj.name == key) tobj.checked = false;
}
}
function completeInsertGrant(ret_obj) {
var error = ret_obj['error'];
var message = ret_obj['message'];
var page = ret_obj['page'];
var module_srl = ret_obj['module_srl'];
alert(message);
location.href = location.href;
}
/* 카테고리 이동 */
function doChangeCategory(fo_obj) {
var module_category_srl = fo_obj.module_category_srl.options[fo_obj.module_category_srl.selectedIndex].value;
if(module_category_srl==-1) {
location.href = current_url.setQuery('act','dispModuleAdminCategory');
return false;
}
return true;
}

View file

@ -0,0 +1,116 @@
<!--#include("./header.html")-->
<form action="./" method="post" enctype="multipart/form-data" target="hidden_iframe">
<input type="hidden" name="module" value="{$module_info->module}" />
<input type="hidden" name="mid" value="{$mid}" />
<input type="hidden" name="act" value="procSpringnoteAdminUpdateSkinInfo" />
<input type="hidden" name="module_srl" value="{$module_srl}" />
<input type="hidden" name="page" value="{$page}" />
<table cellspacing="0" class="adminTable">
<col width="150" />
<col />
<caption>{$lang->skin_default_info}</caption>
<tr>
<th scope="row">{$lang->skin}</th>
<td class="left" >{$skin_info->title}</td>
</tr>
<tr>
<th scope="row">{$lang->skin_maker}</th>
<td class="left" >{$skin_info->maker->name} <!--@if($skin_info->maker->email_address)-->(<a href="mailto:{$skin_info->maker->email_address}">{$skin_info->maker->email_address}</a>)<!--@end--></td>
</tr>
<tr>
<th scope="row">{$lang->skin_maker_homepage}</th>
<td class="left" ><a href="{$skin_info->maker->homepage}" target="_blank">{$skin_info->maker->homepage}</a></td>
</tr>
<tr>
<th scope="row">{$lang->date}</th>
<td class="left" >{$skin_info->maker->date}</td>
</tr>
<tr>
<th scope="row">{$lang->description}</th>
<td class="left" >{nl2br($skin_info->maker->description)}</td>
</tr>
</table>
<table cellspacing="0" class="adminTable">
<col width="150" />
<col />
<caption>{$lang->extra_vars}</caption>
<tr valign="top">
<th scope="row">{$lang->colorset}</th>
<td class="left" >
<!--@foreach($skin_info->colorset as $key => $val)-->
<div>
<!--@if($val->screenshot)-->
<img src="{$val->screenshot}" align="left" alt="{$val->title}" />
<!--@end-->
<input type="radio" name="colorset" value="{$val->name}" id="colorset_{$key}" <!--@if($module_info->colorset==$val->name)-->checked="checked"<!--@end-->/>
<label for="colorset_{$key}">{$val->title}</label>
</div>
<!--@end-->
</td>
</tr>
<!--@foreach($skin_info->extra_vars as $key => $val)-->
<tr>
<th scope="row">{$val->title}</th>
<td class="left">
<!--@if($val->type=="text")-->
<input type="text" name="{$val->name}" value="{htmlspecialchars($val->value)}" class="inputTypeText w100" />
<!--@elseif($val->type=="textarea")-->
<textarea name="{$val->name}" class="inputTypeTextArea w100">{htmlspecialchars($val->value)}</textarea>
<!--@elseif($val->type=="select")-->
<select name="{$val->name}">
<!--@foreach($val->default as $k=>$v)-->
<option value="{$v}" <!--@if($v==$val->value)-->selected="selected"<!--@end-->>{$v}</option>
<!--@end-->
</select>
<!--@elseif($val->type=="checkbox")-->
<!--@foreach($val->default as $k=>$v)-->
<span>
<input type="checkbox" name="{$val->name}[]" value="{$v}" id="ch_{$key}_{$k}" <!--@if(in_array($v, $val->value))-->checked="checked"<!--@end--> class="checkbox" />
<label for="ch_{$key}_{$k}">{$v}</label>
</span>
<!--@end-->
<!--@elseif($val->type=="radio")-->
<!--@foreach($val->default as $k=>$v)-->
<span>
<input type="radio" name="{$val->name}" value="{$v}" id="ch_{$key}_{$k}" <!--@if($v==$val->value)-->checked="checked"<!--@end-->/>
<label for="ch_{$key}_{$k}">{$v}</label>
</span>
<!--@end-->
<!--@elseif($val->type=="image")-->
<!--@if($val->value)-->
<div>
<img src="{$val->value}" /><br />
<input type="checkbox" name="del_{$val->name}" value="Y" id="del_{$val->name}" class="checkbox" />
<label for="del_{$val->name}">{$lang->cmd_delete}</label>
</div>
<!--@end-->
<input type="file" name="{$val->name}" value="" />
<!--@end-->
<!--@if($val->description)-->
<p>{nl2br($val->description)}</p>
<!--@end-->
</td>
</tr>
<!--@end-->
<tr>
<th scope="row" colspan="2" class="button">
<span class="button"><input type="submit" value="{$lang->cmd_registration}" accesskey="s" /></span>
</th>
</tr>
</table>
</form>
<iframe name="hidden_iframe" frameborder="0" style="display:none"></iframe>

View file

@ -0,0 +1,31 @@
<!--%import("filter/delete_springnote.xml")-->
<!--%import("js/springnote_admin.js")-->
<!--#include("header.html")-->
<form action="./" method="get" onsubmit="return procFilter(this, delete_springnote)">
<input type="hidden" name="page" value="{$page}" />
<input type="hidden" name="module_srl" value="{$module_info->module_srl}" />
<table cellspacing="0" class="adminTable">
<col width="150" />
<col />
<tr>
<th scope="row" colspan="2">{$lang->confirm_delete}</th>
</tr>
<tr>
<th scope="row">{$lang->module_name}</th>
<td>{$module_info->mid}</td>
</tr>
<tr>
<th scope="row">{$lang->module}</th>
<td>{$module_info->module}</td>
</tr>
<tr>
<th scope="row" colspan="2" class="button">
<a href="{getUrl('act','dispSpringnoteAdminContent')}" class="button"><span>{$lang->cmd_back}</span></a>
<span class="button"><input type="submit" value="{$lang->cmd_delete}" /></span>
</th>
</tr>
</table>
</form>

View file

@ -0,0 +1,83 @@
<!--#include("header.html")-->
<table cellspacing="0" class="adminTable">
<col width="150" />
<col />
<tr>
<th scope="row">{$lang->module_category}</th>
<td>
<!--@if(!$module_info->module_category_srl)-->
{$lang->not_exists}
<!--@else-->
{$module_category[$module_info->module_category_srl]->title}
<!--@end-->
</td>
</tr>
<tr>
<th scope="row">{$lang->springnote_openid}</th>
<td>http://{$module_info->openid}/</td>
</tr>
<tr>
<th scope="row">{$lang->springnote_userkey}</th>
<td>{$module_info->userkey}&nbsp;</td>
</tr>
<tr>
<th scope="row">{$lang->springnote_pageid}</th>
<td>{$module_info->pageid}&nbsp;</td>
</tr>
<tr>
<th scope="row">{$lang->layout}</th>
<td>
<!--@if($module_info->layout_srl)-->
{$module_info->layout_title} ({$module_info->layout})
<!--@else-->
{$lang->not_exists}
<!--@end-->
&nbsp;
</td>
</tr>
<tr>
<th scope="row">{$lang->skin}</th>
<td>{$module_info->skin_title} ({$module_info->skin})</td>
</tr>
<tr>
<th scope="row">{$lang->browser_title}</th>
<td>{htmlspecialchars($module_info->browser_title)}</td>
</tr>
<tr>
<th scope="row">{$lang->use_category}</th>
<td><!--@if($module_info->use_category=='Y')-->{$lang->use}<!--@else-->{$lang->notuse}<!--@end--></td>
</tr>
<tr>
<th scope="row">{$lang->list_count}</th>
<td>{$module_info->list_count?$module_info->list_count:20}</td>
</tr>
<tr>
<th scope="row">{$lang->page_count}</th>
<td>{$module_info->page_count?$module_info->page_count:10}</td>
</tr>
<tr>
<th scope="row">{$lang->description}</th>
<td>{nl2br(htmlspecialchars($module_info->description))}&nbsp;</td>
</tr>
<tr>
<th scope="row">{$lang->header_text}</th>
<td>{htmlspecialchars($module_info->header_text)}&nbsp;</td>
</tr>
<tr>
<th scope="row">{$lang->footer_text}</th>
<td>{htmlspecialchars($module_info->footer_text)}&nbsp;</td>
</tr>
<tr>
<th scope="row">{$lang->admin_id}</th>
<td>{implode(",",$module_info->admin_id)}&nbsp;</td>
</tr>
<tr>
<th scope="row" colspan="2" class="button">
<a href="{getUrl('act','dispSpringnoteAdminInsertSpringnote')}" class="button"><span>{$lang->cmd_modify}</span></a>
<!--@if($module=="admin")-->
<a href="{getUrl('act','dispSpringnoteAdminContent','module_srl','')}" class="button"><span>{$lang->cmd_springnote_list}</span></a>
<!--@end-->
</th>
</tr>
</table>

View file

@ -0,0 +1,134 @@
<!--%import("filter/insert_springnote.xml")-->
<!--%import("js/springnote_admin.js")-->
<!--#include("header.html")-->
<form action="./" method="post" onsubmit="return procFilter(this, insert_springnote)" enctype="multipart/form-data">
<input type="hidden" name="page" value="{$page}" />
<input type="hidden" name="module_srl" value="{$module_srl}" />
<!--@if($module_info->is_default=='Y')-->
<input type="hidden" name="is_default" value="Y" />
<!--@end-->
<input type="hidden" name="use_category" value="N" />
<table cellspacing="0" class="adminTable">
<col width="150" />
<col />
<tr>
<th scope="row">{$lang->mid}</th>
<td>
<input type="text" name="mid" value="{$module_info->mid}" class="inputTypeText" />
<p>{$lang->about_mid}</p>
</td>
</tr>
<!--@if($module_info->is_default!='Y')-->
<tr>
<th scope="row">{$lang->is_default}</th>
<td>
<input type="checkbox" name="is_default" value="Y" <!--@if($module_info->is_default=='Y')-->checked="checked"<!--@end--> id="fld_for_default" class="checkbox" />
<label for="fld_for_default">{$lang->about_default}</label>
</td>
</tr>
<!--@end-->
<tr>
<th scope="row">{$lang->module_category}</th>
<td>
<select name="module_category_srl">
<option value="0">{$lang->notuse}</option>
<!--@foreach($module_category as $key => $val)-->
<option value="{$key}" <!--@if($module_info->module_category_srl==$key)-->selected="selected"<!--@end-->>{$val->title}</option>
<!--@end-->
</select>
<p>{$lang->about_module_category}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->springnote_openid}</th>
<td>
http://<input type="text" name="springnote_openid" value="{htmlspecialchars($module_info->openid)}" class="inputTypeText w300" />/
<p>{$lang->about_springnote_openid}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->springnote_userkey}</th>
<td>
<input type="text" name="springnote_userkey" value="{htmlspecialchars($module_info->userkey)}" class="inputTypeText w300" />
<p>{$lang->about_springnote_userkey}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->springnote_pageid}</th>
<td>
<input type="text" name="springnote_pageid" value="{htmlspecialchars($module_info->pageid)}" class="inputTypeText w300" />
<p>{$lang->about_springnote_pageid}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->browser_title}</th>
<td>
<input type="text" name="browser_title" value="{htmlspecialchars($module_info->browser_title)}" class="inputTypeText w300" />
<p>{$lang->about_browser_title}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->layout}</th>
<td>
<select name="layout_srl">
<option value="0">{$lang->notuse}</option>
<!--@foreach($layout_list as $key => $val)-->
<option value="{$val->layout_srl}" <!--@if($module_info->layout_srl==$val->layout_srl)-->selected="selected"<!--@end-->>{$val->title} ({$val->layout})</option>
<!--@end-->
</select>
<p>{$lang->about_layout}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->skin}</th>
<td>
<select name="skin">
<!--@foreach($skin_list as $key=>$val)-->
<option value="{$key}" <!--@if($module_info->skin==$key)-->selected="selected"<!--@end-->>{$val->title}</option>
<!--@end-->
</select>
<p>{$lang->about_skin}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->description}</th>
<td>
<textarea name="description" class="inputTypeTextArea w100">{htmlspecialchars($module_info->description)}</textarea>
<p>{$lang->about_description}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->header_text}</th>
<td>
<textarea name="header_text" class="inputTypeTextArea w100">{htmlspecialchars($module_info->header_text)}</textarea>
<p>{$lang->about_header_text}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->footer_text}</th>
<td>
<textarea name="footer_text" class="inputTypeTextArea w100">{htmlspecialchars($module_info->footer_text)}</textarea>
<p>{$lang->about_footer_text}</p>
</td>
</tr>
<tr>
<th scope="row">{$lang->admin_id}</th>
<td>
<textarea name="admin_id" class="inputTypeTextArea w100"><!--@if($module_info->admin_id)-->{implode(",",$module_info->admin_id)}<!--@end--></textarea>
<p>{$lang->about_admin_id}</p>
</td>
</tr>
<tr>
<th scope="row" colspan="2" class="button">
<span class="button"><input type="submit" value="{$lang->cmd_registration}" accesskey="s" /></span>
</th>
</tr>
</table>
</form>