diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/PluginMarket.class.php b/PluginMarket.class.php old mode 100644 new mode 100755 index b81c86d8e3b9920cc618ddd837a950dedb953ada..d027cd244de8800d7697440172ac155b9edf2b29 --- a/PluginMarket.class.php +++ b/PluginMarket.class.php @@ -5,6 +5,17 @@ class PluginMarket extends StudIPPlugin implements SystemPlugin, HomepagePlugin { static protected $studip_domain = null; + static public function getStudipReleases() + { + return array( + '1.4', '1.5', '1.6', '1.7', '1.8', + '1.9', '1.10', '1.11', + '2.0', '2.1', '2.2', '2.3', '2.4', + '2.5', + '3.0', '3.1', '3.2' + ); + } + public function __construct() { parent::__construct(); @@ -15,6 +26,7 @@ class PluginMarket extends StudIPPlugin implements SystemPlugin, HomepagePlugin $top->addSubNavigation("presenting", $overview); $overview->addSubNavigation("overview", new AutoNavigation(_('�bersicht'), PluginEngine::getURL($this, array(), "presenting/overview"))); $overview->addSubNavigation("all", new AutoNavigation(_('Alle Plugins'), PluginEngine::getURL($this, array(), "presenting/all"))); + $overview->addSubNavigation("tools", new AutoNavigation(_('Tools'), PluginEngine::getURL($this, array(), "tools/sidebar_graphics_generator"))); if ($GLOBALS['perm']->have_perm("autor")) { $top->addSubNavigation("myplugins", new Navigation(_("Meine Plugins"), PluginEngine::getURL($this, array(), "myplugins/overview"))); @@ -43,6 +55,7 @@ class PluginMarket extends StudIPPlugin implements SystemPlugin, HomepagePlugin public function initialize() { + PageLayout::addSqueezePackage('lightbox'); $this->addStylesheet('assets/pluginmarket.less'); PageLayout::addHeadElement('link', array( 'rel' => 'alternate', diff --git a/Readme.md b/Readme.md old mode 100644 new mode 100755 diff --git a/assets/pluginmarket.js b/assets/pluginmarket.js old mode 100644 new mode 100755 diff --git a/assets/pluginmarket.less b/assets/pluginmarket.less old mode 100644 new mode 100755 index d19d21d942bd691d2f869f4784fbaaa575831299..6316dc4ff8dba789a991bd40d394fb1b581585a0 --- a/assets/pluginmarket.less +++ b/assets/pluginmarket.less @@ -10,7 +10,7 @@ .flex-justify-content(center); .flex-align-items(stretch); - > .image { + .image { padding: 5px; border: 5px solid #eeeeee; margin: 5px; diff --git a/assets/sidebar-marketplace.png b/assets/sidebar-marketplace.png old mode 100644 new mode 100755 diff --git a/assets/sidebar/jquery.color.js b/assets/sidebar/jquery.color.js new file mode 100755 index 0000000000000000000000000000000000000000..4a825b1995daacbed28e3f4393980509327ba8c9 --- /dev/null +++ b/assets/sidebar/jquery.color.js @@ -0,0 +1,663 @@ +/*! + * jQuery Color Animations v@VERSION + * https://github.com/jquery/jquery-color + * + * Copyright 2013 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * Date: @DATE + */ +(function( jQuery, undefined ) { + + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", + + // plusequals test for += 100 -= 100 + rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, + // a set of RE's that can match strings and generate color tuples. + stringParsers = [{ + re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ], + execResult[ 3 ], + execResult[ 4 ] + ]; + } + }, { + re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ] * 2.55, + execResult[ 2 ] * 2.55, + execResult[ 3 ] * 2.55, + execResult[ 4 ] + ]; + } + }, { + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ], 16 ) + ]; + } + }, { + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) + ]; + } + }, { + re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + space: "hsla", + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ] / 100, + execResult[ 3 ] / 100, + execResult[ 4 ] + ]; + } + }], + + // jQuery.Color( ) + color = jQuery.Color = function( color, green, blue, alpha ) { + return new jQuery.Color.fn.parse( color, green, blue, alpha ); + }, + spaces = { + rgba: { + props: { + red: { + idx: 0, + type: "byte" + }, + green: { + idx: 1, + type: "byte" + }, + blue: { + idx: 2, + type: "byte" + } + } + }, + + hsla: { + props: { + hue: { + idx: 0, + type: "degrees" + }, + saturation: { + idx: 1, + type: "percent" + }, + lightness: { + idx: 2, + type: "percent" + } + } + } + }, + propTypes = { + "byte": { + floor: true, + max: 255 + }, + "percent": { + max: 1 + }, + "degrees": { + mod: 360, + floor: true + } + }, + support = color.support = {}, + + // element for support tests + supportElem = jQuery( "<p>" )[ 0 ], + + // colors = jQuery.Color.names + colors, + + // local aliases of functions called often + each = jQuery.each; + +// determine rgba support immediately + supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; + support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; + +// define cache name and alpha properties +// for rgba and hsla spaces + each( spaces, function( spaceName, space ) { + space.cache = "_" + spaceName; + space.props.alpha = { + idx: 3, + type: "percent", + def: 1 + }; + }); + + function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; + + if ( value == null ) { + return (allowEmpty || !prop.def) ? null : prop.def; + } + + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); + + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { + return prop.def; + } + + if ( type.mod ) { + // we add mod before modding to make sure that negatives values + // get converted properly: -10 -> 350 + return (value + type.mod) % type.mod; + } + + // for now all property types without mod have min and max + return 0 > value ? 0 : type.max < value ? type.max : value; + } + + function stringParse( string ) { + var inst = color(), + rgba = inst._rgba = []; + + string = string.toLowerCase(); + + each( stringParsers, function( i, parser ) { + var parsed, + match = parser.re.exec( string ), + values = match && parser.parse( match ), + spaceName = parser.space || "rgba"; + + if ( values ) { + parsed = inst[ spaceName ]( values ); + + // if this was an rgba parse the assignment might happen twice + // oh well.... + inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; + rgba = inst._rgba = parsed._rgba; + + // exit each( stringParsers ) here because we matched + return false; + } + }); + + // Found a stringParser that handled it + if ( rgba.length ) { + + // if this came from a parsed string, force "transparent" when alpha is 0 + // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) + if ( rgba.join() === "0,0,0,0" ) { + jQuery.extend( rgba, colors.transparent ); + } + return inst; + } + + // named colors + return colors[ string ]; + } + + color.fn = jQuery.extend( color.prototype, { + parse: function( red, green, blue, alpha ) { + if ( red === undefined ) { + this._rgba = [ null, null, null, null ]; + return this; + } + if ( red.jquery || red.nodeType ) { + red = jQuery( red ).css( green ); + green = undefined; + } + + var inst = this, + type = jQuery.type( red ), + rgba = this._rgba = []; + + // more than 1 argument specified - assume ( red, green, blue, alpha ) + if ( green !== undefined ) { + red = [ red, green, blue, alpha ]; + type = "array"; + } + + if ( type === "string" ) { + return this.parse( stringParse( red ) || colors._default ); + } + + if ( type === "array" ) { + each( spaces.rgba.props, function( key, prop ) { + rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); + }); + return this; + } + + if ( type === "object" ) { + if ( red instanceof color ) { + each( spaces, function( spaceName, space ) { + if ( red[ space.cache ] ) { + inst[ space.cache ] = red[ space.cache ].slice(); + } + }); + } else { + each( spaces, function( spaceName, space ) { + var cache = space.cache; + each( space.props, function( key, prop ) { + + // if the cache doesn't exist, and we know how to convert + if ( !inst[ cache ] && space.to ) { + + // if the value was null, we don't need to copy it + // if the key was alpha, we don't need to copy it either + if ( key === "alpha" || red[ key ] == null ) { + return; + } + inst[ cache ] = space.to( inst._rgba ); + } + + // this is the only case where we allow nulls for ALL properties. + // call clamp with alwaysAllowEmpty + inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); + }); + + // everything defined but alpha? + if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + // use the default of 1 + inst[ cache ][ 3 ] = 1; + if ( space.from ) { + inst._rgba = space.from( inst[ cache ] ); + } + } + }); + } + return this; + } + }, + is: function( compare ) { + var is = color( compare ), + same = true, + inst = this; + + each( spaces, function( _, space ) { + var localCache, + isCache = is[ space.cache ]; + if (isCache) { + localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; + each( space.props, function( _, prop ) { + if ( isCache[ prop.idx ] != null ) { + same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); + return same; + } + }); + } + return same; + }); + return same; + }, + _space: function() { + var used = [], + inst = this; + each( spaces, function( spaceName, space ) { + if ( inst[ space.cache ] ) { + used.push( spaceName ); + } + }); + return used.pop(); + }, + transition: function( other, distance ) { + var end = color( other ), + spaceName = end._space(), + space = spaces[ spaceName ], + startColor = this.alpha() === 0 ? color( "transparent" ) : this, + start = startColor[ space.cache ] || space.to( startColor._rgba ), + result = start.slice(); + + end = end[ space.cache ]; + each( space.props, function( key, prop ) { + var index = prop.idx, + startValue = start[ index ], + endValue = end[ index ], + type = propTypes[ prop.type ] || {}; + + // if null, don't override start value + if ( endValue === null ) { + return; + } + // if null - use end + if ( startValue === null ) { + result[ index ] = endValue; + } else { + if ( type.mod ) { + if ( endValue - startValue > type.mod / 2 ) { + startValue += type.mod; + } else if ( startValue - endValue > type.mod / 2 ) { + startValue -= type.mod; + } + } + result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); + } + }); + return this[ spaceName ]( result ); + }, + blend: function( opaque ) { + // if we are already opaque - return ourself + if ( this._rgba[ 3 ] === 1 ) { + return this; + } + + var rgb = this._rgba.slice(), + a = rgb.pop(), + blend = color( opaque )._rgba; + + return color( jQuery.map( rgb, function( v, i ) { + return ( 1 - a ) * blend[ i ] + a * v; + })); + }, + toRgbaString: function() { + var prefix = "rgba(", + rgba = jQuery.map( this._rgba, function( v, i ) { + return v == null ? ( i > 2 ? 1 : 0 ) : v; + }); + + if ( rgba[ 3 ] === 1 ) { + rgba.pop(); + prefix = "rgb("; + } + + return prefix + rgba.join() + ")"; + }, + toHslaString: function() { + var prefix = "hsla(", + hsla = jQuery.map( this.hsla(), function( v, i ) { + if ( v == null ) { + v = i > 2 ? 1 : 0; + } + + // catch 1 and 2 + if ( i && i < 3 ) { + v = Math.round( v * 100 ) + "%"; + } + return v; + }); + + if ( hsla[ 3 ] === 1 ) { + hsla.pop(); + prefix = "hsl("; + } + return prefix + hsla.join() + ")"; + }, + toHexString: function( includeAlpha ) { + var rgba = this._rgba.slice(), + alpha = rgba.pop(); + + if ( includeAlpha ) { + rgba.push( ~~( alpha * 255 ) ); + } + + return "#" + jQuery.map( rgba, function( v ) { + + // default to 0 when nulls exist + v = ( v || 0 ).toString( 16 ); + return v.length === 1 ? "0" + v : v; + }).join(""); + }, + toString: function() { + return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); + } + }); + color.fn.parse.prototype = color.fn; + +// hsla conversions adapted from: +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 + + function hue2rgb( p, q, h ) { + h = ( h + 1 ) % 1; + if ( h * 6 < 1 ) { + return p + (q - p) * h * 6; + } + if ( h * 2 < 1) { + return q; + } + if ( h * 3 < 2 ) { + return p + (q - p) * ((2/3) - h) * 6; + } + return p; + } + + spaces.hsla.to = function ( rgba ) { + if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { + return [ null, null, null, rgba[ 3 ] ]; + } + var r = rgba[ 0 ] / 255, + g = rgba[ 1 ] / 255, + b = rgba[ 2 ] / 255, + a = rgba[ 3 ], + max = Math.max( r, g, b ), + min = Math.min( r, g, b ), + diff = max - min, + add = max + min, + l = add * 0.5, + h, s; + + if ( min === max ) { + h = 0; + } else if ( r === max ) { + h = ( 60 * ( g - b ) / diff ) + 360; + } else if ( g === max ) { + h = ( 60 * ( b - r ) / diff ) + 120; + } else { + h = ( 60 * ( r - g ) / diff ) + 240; + } + + // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% + // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) + if ( diff === 0 ) { + s = 0; + } else if ( l <= 0.5 ) { + s = diff / add; + } else { + s = diff / ( 2 - add ); + } + return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; + }; + + spaces.hsla.from = function ( hsla ) { + if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { + return [ null, null, null, hsla[ 3 ] ]; + } + var h = hsla[ 0 ] / 360, + s = hsla[ 1 ], + l = hsla[ 2 ], + a = hsla[ 3 ], + q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, + p = 2 * l - q; + + return [ + Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), + Math.round( hue2rgb( p, q, h ) * 255 ), + Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), + a + ]; + }; + + + each( spaces, function( spaceName, space ) { + var props = space.props, + cache = space.cache, + to = space.to, + from = space.from; + + // makes rgba() and hsla() + color.fn[ spaceName ] = function( value ) { + + // generate a cache for this space if it doesn't exist + if ( to && !this[ cache ] ) { + this[ cache ] = to( this._rgba ); + } + if ( value === undefined ) { + return this[ cache ].slice(); + } + + var ret, + type = jQuery.type( value ), + arr = ( type === "array" || type === "object" ) ? value : arguments, + local = this[ cache ].slice(); + + each( props, function( key, prop ) { + var val = arr[ type === "object" ? key : prop.idx ]; + if ( val == null ) { + val = local[ prop.idx ]; + } + local[ prop.idx ] = clamp( val, prop ); + }); + + if ( from ) { + ret = color( from( local ) ); + ret[ cache ] = local; + return ret; + } else { + return color( local ); + } + }; + + // makes red() green() blue() alpha() hue() saturation() lightness() + each( props, function( key, prop ) { + // alpha is included in more than one space + if ( color.fn[ key ] ) { + return; + } + color.fn[ key ] = function( value ) { + var vtype = jQuery.type( value ), + fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), + local = this[ fn ](), + cur = local[ prop.idx ], + match; + + if ( vtype === "undefined" ) { + return cur; + } + + if ( vtype === "function" ) { + value = value.call( this, cur ); + vtype = jQuery.type( value ); + } + if ( value == null && prop.empty ) { + return this; + } + if ( vtype === "string" ) { + match = rplusequals.exec( value ); + if ( match ) { + value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); + } + } + local[ prop.idx ] = value; + return this[ fn ]( local ); + }; + }); + }); + +// add cssHook and .fx.step function for each named hook. +// accept a space separated string of properties + color.hook = function( hook ) { + var hooks = hook.split( " " ); + each( hooks, function( i, hook ) { + jQuery.cssHooks[ hook ] = { + set: function( elem, value ) { + var parsed, curElem, + backgroundColor = ""; + + if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { + value = color( parsed || value ); + if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { + curElem = hook === "backgroundColor" ? elem.parentNode : elem; + while ( + (backgroundColor === "" || backgroundColor === "transparent") && + curElem && curElem.style + ) { + try { + backgroundColor = jQuery.css( curElem, "backgroundColor" ); + curElem = curElem.parentNode; + } catch ( e ) { + } + } + + value = value.blend( backgroundColor && backgroundColor !== "transparent" ? + backgroundColor : + "_default" ); + } + + value = value.toRgbaString(); + } + try { + elem.style[ hook ] = value; + } catch( e ) { + // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' + } + } + }; + jQuery.fx.step[ hook ] = function( fx ) { + if ( !fx.colorInit ) { + fx.start = color( fx.elem, hook ); + fx.end = color( fx.end ); + fx.colorInit = true; + } + jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); + }; + }); + + }; + + color.hook( stepHooks ); + + jQuery.cssHooks.borderColor = { + expand: function( value ) { + var expanded = {}; + + each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { + expanded[ "border" + part + "Color" ] = value; + }); + return expanded; + } + }; + +// Basic color names only. +// Usage of any of the other color names requires adding yourself or including +// jquery.color.svg-names.js. + colors = jQuery.Color.names = { + // 4.1. Basic color keywords + aqua: "#00ffff", + black: "#000000", + blue: "#0000ff", + fuchsia: "#ff00ff", + gray: "#808080", + green: "#008000", + lime: "#00ff00", + maroon: "#800000", + navy: "#000080", + olive: "#808000", + purple: "#800080", + red: "#ff0000", + silver: "#c0c0c0", + teal: "#008080", + white: "#ffffff", + yellow: "#ffff00", + + // 4.2.3. "transparent" color keyword + transparent: [ null, null, null, 0 ], + + _default: "#ffffff" + }; + +}( jQuery )); diff --git a/assets/sidebar/sidebar_graphics_generator.js b/assets/sidebar/sidebar_graphics_generator.js new file mode 100755 index 0000000000000000000000000000000000000000..7e5b67edf26e7fc871a6cda2f68e9237e28c5caf --- /dev/null +++ b/assets/sidebar/sidebar_graphics_generator.js @@ -0,0 +1,56 @@ +STUDIP.SidebarGraphicsGenerator = { + file: null, + setFile: function (input) { + var files = input.files; + var file = files[0]; + jQuery("#downloader").attr("download", "sidebar-" + file.name.substr(0, file.name.lastIndexOf(".")) + ".png"); + + var reader = new FileReader; + reader.onload = function () { + STUDIP.SidebarGraphicsGenerator.file = new Image(); + STUDIP.SidebarGraphicsGenerator.file.src = reader.result; + jQuery("#icon").attr("src", reader.result); + window.setTimeout(STUDIP.SidebarGraphicsGenerator.drawImage, 200) + }; + reader.readAsDataURL(file); + jQuery("#save_instructions").show(); + }, + drawImage: function () { + var canvas = window.document.getElementById("sidebar_image"); + var ctx = canvas.getContext("2d"); + ctx.clearRect(0,0,520,200); + ctx.globalAlpha = 1; + ctx.fillStyle = jQuery("#color").val(); + ctx.fillRect(0,0,520,200); + var gradient = ctx.createLinearGradient(0,0,520,0); + gradient.addColorStop(0, "rgba(255,255,255,0.0)"); + gradient.addColorStop(1, "rgba(255,255,255,0.1)"); + ctx.fillStyle = gradient; + ctx.fillRect(0,0,520,200); + + if (STUDIP.SidebarGraphicsGenerator.file !== null) { + var icon = jQuery("#icon")[0]; + var pre_icon = window.document.getElementById("pre_icon"); + var pre_icon_ctx = pre_icon.getContext("2d"); + pre_icon_ctx.globalAlpha = 1; + pre_icon_ctx.clearRect(0, 0, 320, 320); + pre_icon_ctx.drawImage(icon, 0, 0, 320, 320); + + ctx.globalCompositeOperation = "overlay"; + + ctx.globalAlpha = 0.9; + ctx.drawImage(pre_icon, 250, -100, 320, 320); + + ctx.globalAlpha = 0.35; + ctx.drawImage(pre_icon, 20, 50, 300, 300); + + ctx.globalCompositeOperation = "source-over"; + ctx.globalAlpha = 1; + ctx.drawImage(pre_icon, 60, 30, 70, 70); + } + ctx.globalAlpha = 0.5; + ctx.fillStyle = jQuery("#color").val(); + ctx.fillRect(0,140,520,60); + } +}; +jQuery(STUDIP.SidebarGraphicsGenerator.drawImage); \ No newline at end of file diff --git a/assets/star.svg b/assets/star.svg old mode 100644 new mode 100755 diff --git a/assets/star2.svg b/assets/star2.svg old mode 100644 new mode 100755 diff --git a/assets/star3.svg b/assets/star3.svg old mode 100644 new mode 100755 diff --git a/assets/studiptable.js b/assets/studiptable.js old mode 100644 new mode 100755 index cb8c480286411351888c0bcb61320734c99d612b..51b5e2d88d7ffc9056889b0ce27ce6d7b5e249f5 --- a/assets/studiptable.js +++ b/assets/studiptable.js @@ -82,6 +82,9 @@ STUDIP.table = function (element, opt) { } else if (sortType === 'int') { sort1 = parseFloat('0' + $(a).find('td:nth-child(' + headerIndex + ')').text().trim()); sort2 = parseFloat('0' + $(b).find('td:nth-child(' + headerIndex + ')').text().trim()); + } else if (sortType === 'sorter') { + sort1 = parseFloat('0' + $(a).find('td:nth-child(' + headerIndex + ')').data('sorter')); + sort2 = parseFloat('0' + $(b).find('td:nth-child(' + headerIndex + ')').data('sorter')); } else { sort1 = $(a).find('td:nth-child(' + headerIndex + ')').text().trim().toLowerCase(); sort2 = $(b).find('td:nth-child(' + headerIndex + ')').text().trim().toLowerCase(); diff --git a/assets/topicon.svg b/assets/topicon.svg old mode 100644 new mode 100755 diff --git a/assets/topicon_white.svg b/assets/topicon_white.svg old mode 100644 new mode 100755 diff --git a/bootstrap.php b/bootstrap.php old mode 100644 new mode 100755 diff --git a/classes/MarketImage.class.php b/classes/MarketImage.class.php old mode 100644 new mode 100755 diff --git a/classes/MarketPlugin.class.php b/classes/MarketPlugin.class.php old mode 100644 new mode 100755 index ac0fdfc0acdb0f06e2ea382bba366057534ce9f5..9a6960ae61d25d1ab6d9ca8f005edcf9826e1093 --- a/classes/MarketPlugin.class.php +++ b/classes/MarketPlugin.class.php @@ -146,33 +146,20 @@ class MarketPlugin extends SimpleORMap { } public function calculateRating() { - $cache = StudipCacheFactory::getCache(); - $cache_key = 'pluginmarket_rating/'.$this->getId(); - $rating = $cache->read($cache_key); - - if ($rating === false) { - $latest_release_date = $this->releases[0]->mkdate; - $rating = 0; - $factors = 0; - foreach ($this->reviews as $review) { - $factor = (120 * 86400) / ($latest_release_date - $review['chdate']); - if ($factor < 0) { - $factor = 1; - } - if ($factor > 1) { - $factor = 1; - } - $rating += $review['rating'] * $factor * 2; - $factors += $factor; - } - if ($factors > 0) { - $rating /= $factors; - } else { - return $rating = null; - } - - $cache->write($cache_key, $rating, 60 * 5); + $rating = 0; + $factors = 0; + foreach ($this->reviews as $review) { + $age = time() - $review['chdate']; + $factor = (pi() - 2 * atan($age / (86400 * 180))) / pi(); + $rating += $review['rating'] * $factor * 2; + $factors += $factor; + } + if ($factors > 0) { + $rating /= $factors; + } else { + return $rating = null; } + return $rating; } } \ No newline at end of file diff --git a/classes/MarketPluginFollower.class.php b/classes/MarketPluginFollower.class.php old mode 100644 new mode 100755 diff --git a/classes/MarketPluginUsage.php b/classes/MarketPluginUsage.php old mode 100644 new mode 100755 diff --git a/classes/MarketRelease.class.php b/classes/MarketRelease.class.php old mode 100644 new mode 100755 index 4d9bb398928bac4f8faa7b5d5194915b7639eaec..64efa6c4bc509b9bf2fc448ba3ad5722cf2a56be --- a/classes/MarketRelease.class.php +++ b/classes/MarketRelease.class.php @@ -119,6 +119,12 @@ class MarketRelease extends SimpleORMap { } $this['studip_min_version'] = $manifest['studipMinVersion']; $this['studip_max_version'] = $manifest['studipMaxVersion']; + if (!$this['studip_max_version']) { + $versions = PluginMarket::getStudipReleases(); + $manifest['studipMaxVersion'] + = $this['studip_max_version'] + = array_pop($versions).".99"; + } $this['version'] = $manifest['version']; if ($this['repository_overwrites_descriptionfrom']) { $readme = ""; @@ -135,6 +141,7 @@ class MarketRelease extends SimpleORMap { } } $this->store(); + file_put_contents($dir."/plugin.manifest", $this->createManifest($manifest)); $hash = md5(uniqid()); $plugin_raw = $GLOBALS['TMP_PATH']."/plugin_$hash.zip"; create_zip_from_directory($dir, $plugin_raw); @@ -154,4 +161,12 @@ class MarketRelease extends SimpleORMap { && ( !$this->studip_max_version || version_compare($version, $this->studip_max_version) <= 0 ); } + protected function createManifest($manifest) { + $arr = array(); + foreach ($manifest as $index => $value) { + $arr[] = $index."=".$value; + } + return implode("\n", $arr); + } + } \ No newline at end of file diff --git a/classes/MarketReleaseFollower.class.php b/classes/MarketReleaseFollower.class.php old mode 100644 new mode 100755 diff --git a/classes/MarketReview.class.php b/classes/MarketReview.class.php old mode 100644 new mode 100755 diff --git a/composer.json b/composer.json old mode 100644 new mode 100755 diff --git a/composer.lock b/composer.lock old mode 100644 new mode 100755 diff --git a/controllers/approving.php b/controllers/approving.php old mode 100644 new mode 100755 diff --git a/controllers/extern.php b/controllers/extern.php old mode 100644 new mode 100755 diff --git a/controllers/market_controller.php b/controllers/market_controller.php old mode 100644 new mode 100755 index 758157c6d3733bba7ea8f053fa792619fffae2db..3ca1f13fadc949103a5f7fd988791514b201011c --- a/controllers/market_controller.php +++ b/controllers/market_controller.php @@ -3,6 +3,7 @@ require_once 'app/controllers/plugin_controller.php'; class MarketController extends PluginController { + public function absolute_url_for($to) { $old_base = URLHelper::setBaseURL($GLOBALS['ABSOLUTE_URI_STUDIP']); diff --git a/controllers/myplugins.php b/controllers/myplugins.php old mode 100644 new mode 100755 diff --git a/controllers/presenting.php b/controllers/presenting.php old mode 100644 new mode 100755 index 867991e6a6e5b12c43c0f920d31cf53a141c0367..720b3736952e47e942c11328bfed9898806f33a1 --- a/controllers/presenting.php +++ b/controllers/presenting.php @@ -69,10 +69,9 @@ class PresentingController extends MarketController // Create options for all studip versions $_SESSION['pluginmarket']['version'] = Request::submitted('version') ? Request::get('version') : $_SESSION['pluginmarket']['version']; - $studipVersions = array('1.4.0','1.5.0','1.6.0','1.7','1.8','1.9','1.10','1.11','2.0','2.1','2.2','2.3','2.4','2.5','3.0','3.1'); $options[] = "<option value='".URLHelper::getLink('', array('version' => 0))."'>"._('Alle Versionen')."</option>"; - foreach (array_reverse($studipVersions) as $version) { + foreach (array_reverse(PluginMarket::getStudipReleases()) as $version) { $options[] = "<option value='".URLHelper::getLink('', array('version' => $version))."' ".($_SESSION['pluginmarket']['version'] == $version ? "SELECTED" : "").">$version</option>"; } $versionWidget->addElement(new WidgetElement('<select style="width: 100%" onchange="location = this.options[this.selectedIndex].value;">'.join("", $options).'</select>')); @@ -92,7 +91,21 @@ class PresentingController extends MarketController $this->latest_plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY mkdate DESC LIMIT 5"); - $this->best_plugins = MarketPlugin::findBySQL("publiclyvisible = 1 AND approved = 1 ORDER BY rating DESC LIMIT 6"); + $best = DBManager::get()->prepare(" + SELECT pluginmarket_plugins.* + FROM pluginmarket_plugins + LEFT JOIN pluginmarket_reviews ON (pluginmarket_plugins.plugin_id = pluginmarket_reviews.plugin_id) + WHERE publiclyvisible = 1 + AND approved = 1 + GROUP BY pluginmarket_plugins.plugin_id + ORDER BY pluginmarket_plugins.rating DESC, MAX(pluginmarket_reviews.chdate) DESC + LIMIT 6 + "); + $best->execute(); + $this->best_plugins = array(); + foreach ($best->fetchAll(PDO::FETCH_ASSOC) as $data) { + $this->best_plugins[] = MarketPlugin::buildExisting($data); + } $this->render_action('overview_'.$_SESSION['pluginmarket']['view']); } @@ -105,6 +118,7 @@ class PresentingController extends MarketController OR (SELECT CONCAT(Vorname, ' ', Nachname) FROM auth_user_md5 WHERE user_id = pluginmarket_plugins.user_id LIMIT 1) LIKE :likesearch OR MATCH (short_description, description) AGAINST (:search IN BOOLEAN MODE) OR (SELECT GROUP_CONCAT(' ', tag) FROM pluginmarket_tags WHERE pluginmarket_tags.plugin_id = plugin_id GROUP BY pluginmarket_tags.plugin_id LIMIT 1) LIKE :likesearch + OR (SELECT 1 FROM pluginmarket_plugin_usages WHERE pluginmarket_plugins.plugin_id = pluginmarket_plugin_usages.plugin_id AND name LIKE :likesearch LIMIT 1) ) AND publiclyvisible = 1 AND approved = 1 @@ -149,6 +163,14 @@ class PresentingController extends MarketController public function details_action($plugin_id) { Navigation::addItem('/pluginmarket/presenting/details', new AutoNavigation(_('Details'), $this->url_for('presenting/details/'.$plugin_id))); $this->marketplugin = new MarketPlugin($plugin_id); + + if (Request::isPost() && Request::submitted("delete_plugin") && $this->marketplugin->isRootable()) { + $this->marketplugin->delete(); + PageLayout::postMessage(MessageBox::success(_("Plugin wurde gel�scht."))); + $this->redirect('presenting/overview'); + return; + } + $this->marketplugin['rating'] = $this->marketplugin->calculateRating(); $this->marketplugin->store(); diff --git a/controllers/rss.php b/controllers/rss.php old mode 100644 new mode 100755 diff --git a/controllers/tools.php b/controllers/tools.php new file mode 100755 index 0000000000000000000000000000000000000000..5bdbb9509c832b88b54df163fa161c5818b22f14 --- /dev/null +++ b/controllers/tools.php @@ -0,0 +1,11 @@ +<?php +require_once 'market_controller.php'; + +class ToolsController extends MarketController +{ + public function sidebar_graphics_generator_action() + { + PageLayout::addScript($this->plugin->getPluginURL()."/assets/sidebar/jquery.color.js"); + PageLayout::addScript($this->plugin->getPluginURL()."/assets/sidebar/sidebar_graphics_generator.js"); + } +} \ No newline at end of file diff --git a/controllers/update.php b/controllers/update.php old mode 100644 new mode 100755 diff --git a/install.sql b/install.sql old mode 100644 new mode 100755 diff --git a/migrations/01_init_plugin_migration.php b/migrations/01_init_plugin_migration.php old mode 100644 new mode 100755 diff --git a/migrations/02_import_old_data.php b/migrations/02_import_old_data.php old mode 100644 new mode 100755 diff --git a/migrations/03_add_release_secret.php b/migrations/03_add_release_secret.php old mode 100644 new mode 100755 diff --git a/migrations/04_add_rating_to_database.php b/migrations/04_add_rating_to_database.php old mode 100644 new mode 100755 diff --git a/migrations/05_usage_proposals.php b/migrations/05_usage_proposals.php old mode 100644 new mode 100755 diff --git a/plugin.manifest b/plugin.manifest old mode 100644 new mode 100755 index 5a73a83a0d1c756ac47864e7b1c691680041d3b8..01a4c73e6edfd25fda740945f5eb3a537aae179e --- a/plugin.manifest +++ b/plugin.manifest @@ -1,4 +1,4 @@ pluginname=PluginMarktplatz pluginclassname=PluginMarket origin=studip -version=1.0.12 +version=1.0.15 diff --git a/vendor/Parsedown.php b/vendor/Parsedown.php old mode 100644 new mode 100755 diff --git a/vendor/autoload.php b/vendor/autoload.php old mode 100644 new mode 100755 diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php old mode 100644 new mode 100755 diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php old mode 100644 new mode 100755 diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/.gitignore b/vendor/nickcernis/html-to-markdown/.gitignore old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/.travis.yml b/vendor/nickcernis/html-to-markdown/.travis.yml old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/HTML_To_Markdown.php b/vendor/nickcernis/html-to-markdown/HTML_To_Markdown.php old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/LICENSE b/vendor/nickcernis/html-to-markdown/LICENSE old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/README.md b/vendor/nickcernis/html-to-markdown/README.md old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/circle.yml b/vendor/nickcernis/html-to-markdown/circle.yml old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/composer.json b/vendor/nickcernis/html-to-markdown/composer.json old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/demo/index.php b/vendor/nickcernis/html-to-markdown/demo/index.php old mode 100644 new mode 100755 diff --git a/vendor/nickcernis/html-to-markdown/tests/HTML_To_MarkdownTest.php b/vendor/nickcernis/html-to-markdown/tests/HTML_To_MarkdownTest.php old mode 100644 new mode 100755 diff --git a/views/approving/overview.php b/views/approving/overview.php old mode 100644 new mode 100755 diff --git a/views/approving/review.php b/views/approving/review.php old mode 100644 new mode 100755 index 345898d9c942e0c8b547a64bf8faa6248c9a190b..ca32a10c24b0d356ee703fdf2418d662c999847b --- a/views/approving/review.php +++ b/views/approving/review.php @@ -1,4 +1,4 @@ -<form action="<?= $controller->url_for('approving/approve/' . $marketplugin->getId()) ?>" method="post" class="studip_form"> +<form action="<?= $controller->url_for('approving/approve/' . $marketplugin->getId()) ?>" method="post" class="default"> <fieldset> <legend> <?= _("Review schreiben") ?> diff --git a/views/myplugins/_edit_images.php b/views/myplugins/_edit_images.php old mode 100644 new mode 100755 index 0394c8a211ea3c201efd9ff5965af3c1f903e032..1920a0a380607bb88dc58b86f99fb14a99f164fb --- a/views/myplugins/_edit_images.php +++ b/views/myplugins/_edit_images.php @@ -9,7 +9,9 @@ <li class="image"> <input type="checkbox" name="delete_image[]" value="<?= htmlReady($image->getId()) ?>" id="delete_image_<?= htmlReady($image->getId()) ?>"> <div> - <img src="<?= htmlReady($image->getURL()) ?>" style="max-height: 150px;"> + <a href="<?= htmlReady($image->getURL()) ?>" data-lightbox="plugin_gallery"> + <img src="<?= htmlReady($image->getURL()) ?>" style="max-height: 150px;"> + </a> <input type="hidden" name="image_order[]" value="<?= htmlReady($image->getId()) ?>"> <label for="delete_image_<?= htmlReady($image->getId()) ?>"> <?= Assets::img("icons/20/blue/trash", array('style' => "cursor: pointer;")) ?> diff --git a/views/myplugins/_edit_release.php b/views/myplugins/_edit_release.php old mode 100644 new mode 100755 diff --git a/views/myplugins/edit.php b/views/myplugins/edit.php old mode 100644 new mode 100755 index 5eddfbb17e2bec19f145012708e56fc7b8675ce1..f2f932d3f66f13a279f75c7f0962c4a38305c681 --- a/views/myplugins/edit.php +++ b/views/myplugins/edit.php @@ -1,4 +1,4 @@ -<form action="<?= $controller->url_for('myplugins/save') ?>" method="post" class="studip_form" enctype="multipart/form-data"> +<form action="<?= $controller->url_for('myplugins/save') ?>" method="post" class="default" enctype="multipart/form-data"> <input type="hidden" name="id" value="<?= $marketplugin->getId() ?>"> <fieldset> <legend> diff --git a/views/myplugins/edit_images.php b/views/myplugins/edit_images.php old mode 100644 new mode 100755 index 67da92a95093c36413cf9d4f1918237d92da391d..9d90bff9aaf57a35c2395255b4d0442b018ed52b --- a/views/myplugins/edit_images.php +++ b/views/myplugins/edit_images.php @@ -1,4 +1,4 @@ -<form action="<?= $controller->url_for('myplugins/save') ?>" method="post" enctype="multipart/form-data" class="studip_form"> +<form action="<?= $controller->url_for('myplugins/save') ?>" method="post" enctype="multipart/form-data" class="default"> <input type="hidden" name="id" value="<?= $marketplugin->getId() ?>"> <?= $this->render_partial("myplugins/_edit_images.php", compact("marketplugin")) ?> diff --git a/views/myplugins/edit_release.php b/views/myplugins/edit_release.php old mode 100644 new mode 100755 index ca916824a8a5e515a8889384eac8a178aa62ab9d..34b53071c921b428bd6b85171f701f5741fbf425 --- a/views/myplugins/edit_release.php +++ b/views/myplugins/edit_release.php @@ -1,4 +1,4 @@ -<form action="<?= $controller->url_for('myplugins/save_release') ?>" method="post" class="studip_form" enctype="multipart/form-data"> +<form action="<?= $controller->url_for('myplugins/save_release') ?>" method="post" class="default" enctype="multipart/form-data"> <input type="hidden" name="id" value="<?= $release->getId() ?>"> <input type="hidden" name="plugin_id" value="<?= $marketplugin->getId() ?>"> <?= $this->render_partial("myplugins/_edit_release.php", array('release' => $release)) ?> diff --git a/views/myplugins/overview.php b/views/myplugins/overview.php old mode 100644 new mode 100755 diff --git a/views/presenting/_cloud_tag.php b/views/presenting/_cloud_tag.php old mode 100644 new mode 100755 diff --git a/views/presenting/_plugin_short.php b/views/presenting/_plugin_short.php old mode 100644 new mode 100755 diff --git a/views/presenting/all.php b/views/presenting/all.php old mode 100644 new mode 100755 diff --git a/views/presenting/details.php b/views/presenting/details.php old mode 100644 new mode 100755 index 2a44662999e3c0eb58425bb6bfd863821bc410d2..e79791bf06ca1da4ae967fb4905ec64c45683f93 --- a/views/presenting/details.php +++ b/views/presenting/details.php @@ -16,20 +16,31 @@ if ($icon) { <h1><?= htmlReady($marketplugin['name']) ?></h1> <div> - <?= formatReady($marketplugin['description']) ?> + <?= htmlReady($marketplugin['short_description']) ?> </div> - +<?if ($marketplugin['description']) : ?> + <div> + <br> + <?= formatReady($marketplugin['description']) ?> + </div> +<? endif ?> <? if (count($marketplugin->images) > 0 || $marketplugin->isWritable()) : ?> <h2><?= _("Galerie") ?></h2> <ol id="pluginmarket_galery_view" class="pluginmarket_galery"> <? foreach ($marketplugin->images as $image) : ?> <div class="image"> - <img src="<?= htmlReady($image->getURL()) ?>"> + <a href="<?= htmlReady($image->getURL()) ?>" data-lightbox="plugin_gallery"> + <img src="<?= htmlReady($image->getURL()) ?>"> + </a> </div> <? endforeach ?> <? if ($marketplugin->isWritable()) : ?> - <div><a href="<?= $controller->url_for('myplugins/edit_images/' . $marketplugin->getId()) ?>" data-dialog title="<?= _("Galerie bearbeiten / neue Bilder hinzuf�gen") ?>"><?= Assets::img("icons/20/blue/add") ?></a></div> + <div> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit_images/". $marketplugin->getId()) ?>" data-dialog title="<?= _("Galerie bearbeiten / neue Bilder hinzuf�gen") ?>"> + <?= Assets::img("icons/20/blue/add") ?> + </a> + </div> <? endif ?> </ol> <? endif ?> @@ -38,12 +49,14 @@ if ($icon) { <ul class="plugin-usages"> <? foreach ($marketplugin['uses'] as $use): ?> <li> - <?= htmlReady($use->name) ?> + <a href="<?= PluginEngine::getLink($plugin, array('search' => htmlReady($use->name)), "presenting/all") ?>"> + <?= htmlReady($use->name) ?> + </a> <? if ($use->plugin->isWritable(User::findCurrent()->id)): ?> (<?= ObjectdisplayHelper::link($use->user) ?>) <? endif; ?> <? if ($use->isEditable()): ?> - <a href="<?= $controller->url_for('presenting/delete_usage/' . $use->id) ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/delete_usage/" . $use->id) ?>"> <?= Assets::img('icons/blue/trash.svg'); ?> </a> <? endif; ?> @@ -114,7 +127,7 @@ if ($icon) { <? foreach ($marketplugin->releases as $release) : ?> <tr> <td> - <a href="<?= $controller->url_for('presenting/download/' . $release->getId()) ?>" title="<?= _("Dieses Release runterladen") ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/download/". $release->getId()) ?>" title="<?= _("Dieses Release runterladen") ?>"> <?= Assets::img("icons/20/blue/download", array('class' => "text-bottom")) ?> <?= htmlReady($release['version']) ?> </a> @@ -126,15 +139,15 @@ if ($icon) { <td><?= htmlReady($release['downloads']) ?></td> <td class="actions"> <? if ($marketplugin->isWritable()) : ?> - <a href="<?= $controller->url_for('myplugins/edit_release/' . $release->getId()) ?>" data-dialog> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/edit_release/" . $release->getId()) ?>" data-dialog> <?= Assets::img("icons/20/blue/edit", array('class' => "text-bottom")) ?> </a> - <a href="<?= $controller->url_for('presenting/delete_release/' . $release->getId()) ?>"> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/delete_release/" . $release->getId()) ?>"> <?= Assets::img("icons/20/blue/trash", array('class' => "text-bottom", 'onclick' => "return window.confirm('"._("Pluginrelease wirklich unwiderrufbar l�schen?")."');")) ?> </a> <? endif ?> <? if ($GLOBALS['perm']->have_perm("autor")) : ?> - <a href="<?= $controller->url_for('presenting/follow_release/' . $release->getId()) ?>" title="<?= _("F�r automatische Updates registrieren.") ?>" data-dialog> + <a href="<?= PluginEngine::getLink($plugin, array(), "presenting/follow_release/" . $release->getId()) ?>" title="<?= _("F�r automatische Updates registrieren.") ?>" data-dialog> <?= Assets::img("icons/20/blue/rss", array('class' => "text-bottom")) ?> </a> <? endif ?> @@ -146,7 +159,7 @@ if ($icon) { <tfoot> <tr> <td colspan="7"> - <a href="<?= $controller->url_for('myplugins/add_release/' . $marketplugin->getId()) ?>" data-dialog> + <a href="<?= PluginEngine::getLink($plugin, array(), "myplugins/add_release/" . $marketplugin->getId()) ?>" data-dialog> <?= Assets::img("icons/20/blue/add") ?> </a> </td> @@ -234,15 +247,15 @@ if ($icon) { <a <?= ($GLOBALS['perm']->have_perm("autor") && !$marketplugin->isWritable()) ? 'href="' . $controller->url_for('presenting/review/' . $marketplugin->getId()) . '" data-dialog' : "" ?> title="<?= sprintf(_("%s von 5 Sternen"), round($marketplugin['rating'] / 2, 1)) ?>"> <? endif ?> <? $marketplugin['rating'] = round($marketplugin['rating'], 1) / 2 ?> - <? $v = $marketplugin['rating'] >= 1 ? 3 : ($marketplugin['rating'] >= 0.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 0.75 ? 3 : ($marketplugin['rating'] >= 0.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] >= 2 ? 3 : ($marketplugin['rating'] >= 1.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 1.75 ? 3 : ($marketplugin['rating'] >= 1.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] >= 3 ? 3 : ($marketplugin['rating'] >= 2.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 2.75 ? 3 : ($marketplugin['rating'] >= 2.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] >= 4 ? 3 : ($marketplugin['rating'] >= 3.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 3.75 ? 3 : ($marketplugin['rating'] >= 3.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> - <? $v = $marketplugin['rating'] > 4.5 ? 3 : ($marketplugin['rating'] >= 4.5 ? 2 : "") ?> + <? $v = $marketplugin['rating'] >= 4.75 ? 3 : ($marketplugin['rating'] >= 4.25 ? 2 : "") ?> <?= Assets::img($plugin->getPluginURL()."/assets/star$v.svg", array('width' => "50px")) ?> <? if (!$marketplugin->isWritable()) : ?> </a> @@ -282,11 +295,11 @@ if ($icon) { <div style="text-align: center"> <? if ($marketplugin->isWritable()) : ?> - <?= \Studip\LinkButton::create(_("Plugin l�schen"), $controller->url_for('myplugins/delete/' . $marketplugin->getId()), array('data-dialog' => 1)) ?> - <?= \Studip\LinkButton::create(_("bearbeiten"), $controller->url_for('myplugins/edit/' . $marketplugin->getId()), array('data-dialog' => 1)) ?> - <?= \Studip\LinkButton::create(_("Release hinzuf�gen"), $controller->url_for('myplugins/add_release/' . $marketplugin->getId()), array('data-dialog' => 1)) ?> + <?= \Studip\LinkButton::create(_("Plugin l�schen"), PluginEngine::getURL($plugin, array(), 'myplugins/delete/' . $marketplugin->getId()), array('data-dialog' => 1)) ?> + <?= \Studip\LinkButton::create(_("bearbeiten"), PluginEngine::getURL($plugin, array(), "myplugins/edit/" . $marketplugin->getId()), array('data-dialog' => 1)) ?> + <?= \Studip\LinkButton::create(_("Release hinzuf�gen"), PluginEngine::getURL($plugin, array(), "myplugins/add_release/" . $marketplugin->getId()), array('data-dialog' => 1)) ?> <? endif ?> <? if ($marketplugin['user_id'] !== $GLOBALS['user']->id) : ?> - <?= \Studip\LinkButton::create(_("Plugin abonnieren"), $controller->url_for('presenting/register_for_pluginnews/' . $marketplugin->getId()), array('title' => _("Neuigkeiten des Plugins per Nachricht bekommen."), 'data-dialog' => "1")) ?> + <?= \Studip\LinkButton::create(_("Plugin abonnieren"), PluginEngine::getURL($plugin, array(), "presenting/register_for_pluginnews/" . $marketplugin->getId()), array('title' => _("Neuigkeiten des Plugins per Nachricht bekommen."), 'data-dialog' => "1")) ?> <? endif ?> </div> diff --git a/views/presenting/follow_release.php b/views/presenting/follow_release.php old mode 100644 new mode 100755 index 565ed67ef72748686961ec8adc94ad8a38bc20ab..748b46322af9ff5acee3ba7ec3f54bf9b829d6d1 --- a/views/presenting/follow_release.php +++ b/views/presenting/follow_release.php @@ -1,7 +1,7 @@ <? foreach (PageLayout::getMessages() as $message) : ?> <?= $message ?> <? endforeach ?> -<form action="<?= $controller->url_for('presenting/follow_release/' . $release->getId()) ?>" method="post" data-dialog class="studip_form"> +<form action="<?= $controller->url_for('presenting/follow_release/' . $release->getId()) ?>" method="post" data-dialog class="default"> <p class="info"> <?= _("Immer aktuell bleiben mit automatischen Updates! Sie finden in Ihrem eigenen Stud.IP in der Pluginverwaltung rechts neben dem Plugin ein Icon, das Sie zu einem Popup f�hrt. Geben Sie dort die unten stehende Download-URL ein und geben Sie hier die URL ein, die Sie danach dort in Ihrer Pluginverwaltung sehen. Sind beide Systeme korrekt konfiguriert, wird der Marktplatz dann eine jede neue Version dieses Releases automatisch in ihrem Stud.IP installieren.") ?> </p> diff --git a/views/presenting/overview_list.php b/views/presenting/overview_list.php old mode 100644 new mode 100755 index 7f4c65a7c2c68a356cb89051d3418d9d5db4a783..6287307741be273b81bf4a1976ed41d0a26e828c --- a/views/presenting/overview_list.php +++ b/views/presenting/overview_list.php @@ -10,7 +10,7 @@ <th data-sort-type="int"> <?= _('Standorte') ?> </th> - <th data-sort-type="int"> + <th data-sort-type="sorter"> <?= _('Letzte �nderung') ?> </th> <th data-sort-type="int"> @@ -32,8 +32,8 @@ <td> <?= htmlReady($marketplugin->uses->count()) ?> </td> - <td> - <?= strftime('%x', $marketplugin->releases->orderBy('chdate DESC')->first()->chdate) ?> + <td data-sorter="<?= $marketplugin->releases->orderBy('chdate DESC')->val('mkdate') ?>"> + <?= strftime('%x', $marketplugin->releases->orderBy('chdate DESC')->val('mkdate')) ?> </td> <td> <?= htmlReady($marketplugin->getDownloads()) ?> diff --git a/views/presenting/overview_tiles.php b/views/presenting/overview_tiles.php old mode 100644 new mode 100755 diff --git a/views/presenting/propose_usage.php b/views/presenting/propose_usage.php old mode 100644 new mode 100755 index 350adfae0fd88e0ca8a53ed83ccafe5730789456..a5a17c948b8ef803d76f66c4d285ab63f7bad305 --- a/views/presenting/propose_usage.php +++ b/views/presenting/propose_usage.php @@ -1,4 +1,4 @@ -<form class="studip_form" method="post" action="<?= $controller->url_for('presenting/propose_usage/' . $plugin->id) ?>"> +<form class="default" method="post" action="<?= $controller->url_for('presenting/propose_usage/' . $plugin->id) ?>"> <fieldset> <?= CSRFProtection::tokenTag(); ?> <legend><?= sprintf(_('Pluginnutzung mitteilen f�r %s'), htmlReady($plugin->name)) ?></legend> diff --git a/views/presenting/register_for_pluginnews.php b/views/presenting/register_for_pluginnews.php old mode 100644 new mode 100755 diff --git a/views/presenting/review.php b/views/presenting/review.php old mode 100644 new mode 100755 index 0d01c936af856a2f40425a8085b6d3608e8f0f16..56a4421b57b634db6214d0c292025ff4958b90d3 --- a/views/presenting/review.php +++ b/views/presenting/review.php @@ -1,4 +1,4 @@ -<form action="<?= $controller->url_for('presenting/save_review/' . $review['plugin_id']) ?>" method="post" class="studip_form"> +<form action="<?= $controller->url_for('presenting/save_review/' . $review['plugin_id']) ?>" method="post" class="default"> <fieldset> <legend> <?= _("Bewertung") ?> diff --git a/views/presenting/users_plugins.php b/views/presenting/users_plugins.php old mode 100644 new mode 100755 diff --git a/views/tools/sidebar_graphics_generator.php b/views/tools/sidebar_graphics_generator.php new file mode 100755 index 0000000000000000000000000000000000000000..b9514828af773704b5f8560d557d2488f5d53a98 --- /dev/null +++ b/views/tools/sidebar_graphics_generator.php @@ -0,0 +1,34 @@ +<h2><?= _("Erstellen von Sidebar-Grafiken") ?></h2> + +<table> + <tbody> + <tr> + <td><label for="color"><?=_("Farbe") ?></label></td> + <td><input type="color" id="color" value="#24437c" onChange="STUDIP.SidebarGraphicsGenerator.drawImage();"></td> + </tr> + <tr> + <td><label for="localicon"><?= _("Bilddatei (SVG, quadratisch, weiß)") ?></label></td> + <td><input type="file" id="localicon" onChange="STUDIP.SidebarGraphicsGenerator.setFile(this); return false;"></td> + </tr> + <tr style="display: none;"> + <td><?= _("Bild") ?></td> + <td><img id="icon" style="width: 200px; height: 200px; background-color: #36598f; border:thin solid #36598f"></td> + </tr> + </tbody> +</table> + + +<canvas width="320" height="320" style="display: none;" id="pre_icon"></canvas> + +<input type="hidden" id="filename" value=""> + +<div style="border: rgba(54,89,142,0.5) solid 10px; display: inline-block; border-radius: 7px;"> + <canvas width="520px" height="200px" style="border: white solid 3px;" id="sidebar_image"></canvas> +</div> + +<div id="save_instructions" style="display: none; padding: 20px;"> + <a href="#" id="downloader" onClick="this.href=window.document.getElementById('sidebar_image').toDataURL('image/png');" download="testXXX.png"> + <?= Assets::img("icons/16/blue/download") ?> + <?= _("Speichern unter ...") ?> + </a> +</div>